one 1.10.1 → 1.10.3
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/devtools/source-inspector.mjs +157 -25
- package/dist/cjs/cli/build.cjs +3 -5
- package/dist/cjs/cli/build.js +3 -5
- package/dist/cjs/cli/build.js.map +1 -1
- package/dist/cjs/cli/build.native.js +3 -5
- package/dist/cjs/cli/build.native.js.map +1 -1
- package/dist/cjs/cli/buildPage.cjs +8 -8
- package/dist/cjs/cli/buildPage.js +5 -6
- package/dist/cjs/cli/buildPage.js.map +1 -1
- package/dist/cjs/cli/buildPage.native.js +6 -8
- package/dist/cjs/cli/buildPage.native.js.map +1 -1
- package/dist/cjs/cli/daemon.cjs +2 -4
- package/dist/cjs/cli/daemon.js +2 -2
- package/dist/cjs/cli/daemon.js.map +1 -1
- package/dist/cjs/cli/daemon.native.js +2 -4
- package/dist/cjs/cli/daemon.native.js.map +1 -1
- package/dist/cjs/createHandleRequest.cjs +2 -2
- package/dist/cjs/createHandleRequest.js +2 -2
- package/dist/cjs/createHandleRequest.js.map +1 -1
- package/dist/cjs/createHandleRequest.native.js +2 -2
- package/dist/cjs/createHandleRequest.native.js.map +1 -1
- package/dist/cjs/daemon/server.cjs +8 -14
- package/dist/cjs/daemon/server.js +8 -14
- package/dist/cjs/daemon/server.js.map +1 -1
- package/dist/cjs/daemon/server.native.js +10 -16
- package/dist/cjs/daemon/server.native.js.map +1 -1
- package/dist/cjs/daemon/tui.cjs +7 -10
- package/dist/cjs/daemon/tui.js +12 -24
- package/dist/cjs/daemon/tui.js.map +1 -1
- package/dist/cjs/daemon/tui.native.js +5 -7
- package/dist/cjs/daemon/tui.native.js.map +1 -1
- package/dist/cjs/router/getRoutes.cjs +2 -2
- package/dist/cjs/router/getRoutes.js +2 -2
- package/dist/cjs/router/getRoutes.js.map +1 -1
- package/dist/cjs/router/getRoutes.native.js +2 -2
- package/dist/cjs/router/getRoutes.native.js.map +1 -1
- package/dist/cjs/router/interceptRoutes.cjs +5 -8
- package/dist/cjs/router/interceptRoutes.js +5 -9
- package/dist/cjs/router/interceptRoutes.js.map +1 -1
- package/dist/cjs/router/interceptRoutes.native.js +5 -8
- package/dist/cjs/router/interceptRoutes.native.js.map +1 -1
- package/dist/cjs/router/router.js.map +1 -1
- package/dist/cjs/router/router.native.js.map +1 -1
- package/dist/cjs/server/oneServe.cjs +41 -57
- package/dist/cjs/server/oneServe.js +41 -45
- package/dist/cjs/server/oneServe.js.map +1 -1
- package/dist/cjs/server/oneServe.native.js +54 -73
- package/dist/cjs/server/oneServe.native.js.map +1 -1
- package/dist/cjs/useLoader.cjs +5 -10
- package/dist/cjs/useLoader.js +10 -16
- package/dist/cjs/useLoader.js.map +1 -1
- package/dist/cjs/useLoader.native.js +5 -10
- package/dist/cjs/useLoader.native.js.map +1 -1
- package/dist/cjs/utils/redirect.cjs +1 -1
- package/dist/cjs/utils/redirect.js +1 -1
- package/dist/cjs/utils/redirect.js.map +1 -1
- package/dist/cjs/utils/redirect.native.js +1 -1
- package/dist/cjs/utils/redirect.native.js.map +1 -1
- package/dist/cjs/views/Navigator.cjs +1 -1
- package/dist/cjs/views/Navigator.js +1 -1
- package/dist/cjs/views/Navigator.js.map +1 -1
- package/dist/cjs/views/Navigator.native.js +1 -3
- package/dist/cjs/views/Navigator.native.js.map +1 -1
- package/dist/cjs/vite/one.cjs +1 -19
- package/dist/cjs/vite/one.js +1 -20
- package/dist/cjs/vite/one.js.map +1 -1
- package/dist/cjs/vite/one.native.js +1 -17
- package/dist/cjs/vite/one.native.js.map +1 -1
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.cjs +2 -7
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.js +3 -7
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.js.map +1 -1
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.native.js +2 -44
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.native.js.map +1 -1
- package/dist/esm/cli/build.js +3 -5
- package/dist/esm/cli/build.js.map +1 -1
- package/dist/esm/cli/build.mjs +3 -5
- package/dist/esm/cli/build.mjs.map +1 -1
- package/dist/esm/cli/build.native.js +3 -5
- package/dist/esm/cli/build.native.js.map +1 -1
- package/dist/esm/cli/buildPage.js +5 -6
- package/dist/esm/cli/buildPage.js.map +1 -1
- package/dist/esm/cli/buildPage.mjs +8 -8
- package/dist/esm/cli/buildPage.mjs.map +1 -1
- package/dist/esm/cli/buildPage.native.js +6 -8
- package/dist/esm/cli/buildPage.native.js.map +1 -1
- package/dist/esm/cli/daemon.js +2 -2
- package/dist/esm/cli/daemon.js.map +1 -1
- package/dist/esm/cli/daemon.mjs +2 -4
- package/dist/esm/cli/daemon.mjs.map +1 -1
- package/dist/esm/cli/daemon.native.js +2 -4
- package/dist/esm/cli/daemon.native.js.map +1 -1
- package/dist/esm/createHandleRequest.js +2 -2
- package/dist/esm/createHandleRequest.js.map +1 -1
- package/dist/esm/createHandleRequest.mjs +2 -2
- package/dist/esm/createHandleRequest.mjs.map +1 -1
- package/dist/esm/createHandleRequest.native.js +2 -2
- package/dist/esm/createHandleRequest.native.js.map +1 -1
- package/dist/esm/daemon/server.js +8 -14
- package/dist/esm/daemon/server.js.map +1 -1
- package/dist/esm/daemon/server.mjs +8 -14
- package/dist/esm/daemon/server.mjs.map +1 -1
- package/dist/esm/daemon/server.native.js +10 -16
- package/dist/esm/daemon/server.native.js.map +1 -1
- package/dist/esm/daemon/tui.js +12 -24
- package/dist/esm/daemon/tui.js.map +1 -1
- package/dist/esm/daemon/tui.mjs +7 -10
- package/dist/esm/daemon/tui.mjs.map +1 -1
- package/dist/esm/daemon/tui.native.js +6 -8
- package/dist/esm/daemon/tui.native.js.map +1 -1
- package/dist/esm/router/getRoutes.js +2 -2
- package/dist/esm/router/getRoutes.js.map +1 -1
- package/dist/esm/router/getRoutes.mjs +2 -2
- package/dist/esm/router/getRoutes.mjs.map +1 -1
- package/dist/esm/router/getRoutes.native.js +2 -2
- package/dist/esm/router/getRoutes.native.js.map +1 -1
- package/dist/esm/router/interceptRoutes.js +5 -9
- package/dist/esm/router/interceptRoutes.js.map +1 -1
- package/dist/esm/router/interceptRoutes.mjs +6 -8
- package/dist/esm/router/interceptRoutes.mjs.map +1 -1
- package/dist/esm/router/interceptRoutes.native.js +6 -8
- package/dist/esm/router/interceptRoutes.native.js.map +1 -1
- package/dist/esm/router/router.js.map +1 -1
- package/dist/esm/router/router.mjs.map +1 -1
- package/dist/esm/router/router.native.js.map +1 -1
- package/dist/esm/server/oneServe.js +41 -45
- package/dist/esm/server/oneServe.js.map +1 -1
- package/dist/esm/server/oneServe.mjs +41 -57
- package/dist/esm/server/oneServe.mjs.map +1 -1
- package/dist/esm/server/oneServe.native.js +54 -73
- package/dist/esm/server/oneServe.native.js.map +1 -1
- package/dist/esm/useLoader.js +10 -16
- package/dist/esm/useLoader.js.map +1 -1
- package/dist/esm/useLoader.mjs +5 -10
- package/dist/esm/useLoader.mjs.map +1 -1
- package/dist/esm/useLoader.native.js +5 -10
- package/dist/esm/useLoader.native.js.map +1 -1
- package/dist/esm/utils/redirect.js +1 -1
- package/dist/esm/utils/redirect.js.map +1 -1
- package/dist/esm/utils/redirect.mjs +1 -1
- package/dist/esm/utils/redirect.mjs.map +1 -1
- package/dist/esm/utils/redirect.native.js +1 -1
- package/dist/esm/utils/redirect.native.js.map +1 -1
- package/dist/esm/views/Navigator.js +1 -1
- package/dist/esm/views/Navigator.js.map +1 -1
- package/dist/esm/views/Navigator.mjs +1 -1
- package/dist/esm/views/Navigator.mjs.map +1 -1
- package/dist/esm/views/Navigator.native.js +1 -3
- package/dist/esm/views/Navigator.native.js.map +1 -1
- package/dist/esm/vite/one.js +1 -20
- package/dist/esm/vite/one.js.map +1 -1
- package/dist/esm/vite/one.mjs +1 -19
- package/dist/esm/vite/one.mjs.map +1 -1
- package/dist/esm/vite/one.native.js +1 -17
- package/dist/esm/vite/one.native.js.map +1 -1
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.js +3 -7
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.js.map +1 -1
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.mjs +2 -7
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.mjs.map +1 -1
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.native.js +2 -44
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.native.js.map +1 -1
- package/package.json +9 -9
- package/src/cli/build.ts +3 -20
- package/src/cli/buildPage.ts +5 -7
- package/src/cli/daemon.ts +2 -2
- package/src/createHandleRequest.ts +2 -1
- package/src/daemon/server.ts +11 -23
- package/src/daemon/tui.ts +11 -29
- package/src/router/getRoutes.ts +3 -4
- package/src/router/interceptRoutes.ts +5 -30
- package/src/router/router.ts +0 -3
- package/src/server/oneServe.ts +67 -108
- package/src/useLoader.ts +17 -27
- package/src/utils/redirect.ts +1 -1
- package/src/views/Navigator.tsx +1 -3
- package/src/vite/one.ts +2 -100
- package/src/vite/plugins/fileSystemRouterPlugin.tsx +3 -50
- package/types/cli/build.d.ts.map +1 -1
- package/types/createHandleRequest.d.ts.map +1 -1
- package/types/daemon/server.d.ts.map +1 -1
- package/types/daemon/tui.d.ts.map +1 -1
- package/types/router/getRoutes.d.ts.map +1 -1
- package/types/router/interceptRoutes.d.ts +0 -1
- package/types/router/interceptRoutes.d.ts.map +1 -1
- package/types/router/router.d.ts.map +1 -1
- package/types/server/oneServe.d.ts.map +1 -1
- package/types/useLoader.d.ts.map +1 -1
- package/types/views/Navigator.d.ts.map +1 -1
- package/types/vite/one.d.ts.map +1 -1
- package/types/vite/plugins/fileSystemRouterPlugin.d.ts.map +1 -1
package/src/daemon/tui.ts
CHANGED
|
@@ -52,6 +52,14 @@ interface TUIState {
|
|
|
52
52
|
popup: { message: string; timeout: NodeJS.Timeout } | null
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
const CABLE_COLORS = [
|
|
56
|
+
colors.green,
|
|
57
|
+
colors.cyan,
|
|
58
|
+
colors.magenta,
|
|
59
|
+
colors.blue,
|
|
60
|
+
colors.yellow,
|
|
61
|
+
]
|
|
62
|
+
|
|
55
63
|
const ESC = '\x1b'
|
|
56
64
|
const CSI = `${ESC}[`
|
|
57
65
|
|
|
@@ -447,8 +455,6 @@ async function refreshData(): Promise<void> {
|
|
|
447
455
|
tuiState.simulators = newSims
|
|
448
456
|
tuiState.servers = newServers
|
|
449
457
|
|
|
450
|
-
const isDragging = tuiState.draggingSimIndex !== null
|
|
451
|
-
|
|
452
458
|
// get actual simulator -> server mappings from routing state
|
|
453
459
|
const simMappings = getSimulatorMappings()
|
|
454
460
|
|
|
@@ -558,15 +564,7 @@ function render(): void {
|
|
|
558
564
|
const isSelected = tuiState.selectedCol === 0 && tuiState.selectedRow === row
|
|
559
565
|
const cable = tuiState.cables.get(row)
|
|
560
566
|
const hasConnection = cable?.serverIndex !== null
|
|
561
|
-
|
|
562
|
-
const cableColors = [
|
|
563
|
-
colors.green,
|
|
564
|
-
colors.cyan,
|
|
565
|
-
colors.magenta,
|
|
566
|
-
colors.blue,
|
|
567
|
-
colors.yellow,
|
|
568
|
-
]
|
|
569
|
-
const cableColor = cableColors[row % cableColors.length]
|
|
567
|
+
const cableColor = CABLE_COLORS[row % CABLE_COLORS.length]
|
|
570
568
|
const plug = hasConnection ? cableColor('●') : colors.dim('○')
|
|
571
569
|
const name = truncate(sim.name, simEndX - 5)
|
|
572
570
|
simText = `${name} ${plug}`
|
|
@@ -591,18 +589,10 @@ function render(): void {
|
|
|
591
589
|
let srvRight = ''
|
|
592
590
|
if (server) {
|
|
593
591
|
const isSelected = tuiState.selectedCol === 1 && tuiState.selectedRow === row
|
|
594
|
-
// check which cables are connected to this server and get their colors
|
|
595
|
-
const cableColors = [
|
|
596
|
-
colors.green,
|
|
597
|
-
colors.cyan,
|
|
598
|
-
colors.magenta,
|
|
599
|
-
colors.blue,
|
|
600
|
-
colors.yellow,
|
|
601
|
-
]
|
|
602
592
|
let connectedColor: ((s: string) => string) | null = null
|
|
603
593
|
for (const [simIndex, cable] of tuiState.cables) {
|
|
604
594
|
if (cable.serverIndex === row) {
|
|
605
|
-
connectedColor =
|
|
595
|
+
connectedColor = CABLE_COLORS[simIndex % CABLE_COLORS.length]
|
|
606
596
|
break
|
|
607
597
|
}
|
|
608
598
|
}
|
|
@@ -695,15 +685,7 @@ function getCableCharAt(x: number, y: number): string | null {
|
|
|
695
685
|
|
|
696
686
|
if (px === x && py === y) {
|
|
697
687
|
const connected = cable.serverIndex !== null
|
|
698
|
-
|
|
699
|
-
const cableColors = [
|
|
700
|
-
colors.green,
|
|
701
|
-
colors.cyan,
|
|
702
|
-
colors.magenta,
|
|
703
|
-
colors.blue,
|
|
704
|
-
colors.yellow,
|
|
705
|
-
]
|
|
706
|
-
const baseColor = cableColors[simIndex % cableColors.length]
|
|
688
|
+
const baseColor = CABLE_COLORS[simIndex % CABLE_COLORS.length]
|
|
707
689
|
const color = connected ? baseColor : colors.dim
|
|
708
690
|
|
|
709
691
|
// determine character based on curve direction
|
package/src/router/getRoutes.ts
CHANGED
|
@@ -536,7 +536,7 @@ function getFileMeta(
|
|
|
536
536
|
const isLayout = filenameWithoutExtensions.startsWith('_layout')
|
|
537
537
|
const isMiddleware = filenameWithoutExtensions.startsWith('_middleware')
|
|
538
538
|
|
|
539
|
-
const [
|
|
539
|
+
const [, renderModeFound] =
|
|
540
540
|
filename.match(/\+(api|ssg|ssr|spa)\.(\w+\.)?[jt]sx?$/) || []
|
|
541
541
|
const fileRenderMode = renderModeFound as 'api' | One.RouteRenderMode | undefined
|
|
542
542
|
|
|
@@ -656,6 +656,7 @@ function getFileMeta(
|
|
|
656
656
|
}
|
|
657
657
|
|
|
658
658
|
function getMostSpecific(routes: RouteNode[]) {
|
|
659
|
+
// holey array: .length includes holes, so last element is most specific
|
|
659
660
|
const route = routes[routes.length - 1]
|
|
660
661
|
|
|
661
662
|
if (!routes[0]) {
|
|
@@ -664,9 +665,7 @@ function getMostSpecific(routes: RouteNode[]) {
|
|
|
664
665
|
)
|
|
665
666
|
}
|
|
666
667
|
|
|
667
|
-
|
|
668
|
-
// `.length` includes the holes in its count
|
|
669
|
-
return routes[routes.length - 1]
|
|
668
|
+
return route
|
|
670
669
|
}
|
|
671
670
|
|
|
672
671
|
export function getIgnoreList(options?: Options) {
|
|
@@ -27,10 +27,6 @@ export function isHardNavigation(): boolean {
|
|
|
27
27
|
return navigationMode === 'hard'
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export function isSoftNavigation(): boolean {
|
|
31
|
-
return navigationMode === 'soft'
|
|
32
|
-
}
|
|
33
|
-
|
|
34
30
|
// ============================================
|
|
35
31
|
// Intercept Route Matching
|
|
36
32
|
// ============================================
|
|
@@ -241,8 +237,7 @@ function findMatchingInterceptInSlot(
|
|
|
241
237
|
const resolvedTargetPath = resolveInterceptTargetPath(
|
|
242
238
|
interceptTargetPath,
|
|
243
239
|
levels,
|
|
244
|
-
layoutNode
|
|
245
|
-
currentPath
|
|
240
|
+
layoutNode
|
|
246
241
|
)
|
|
247
242
|
|
|
248
243
|
// Try to match the target path against the resolved intercept path
|
|
@@ -273,24 +268,11 @@ function findMatchingInterceptInSlot(
|
|
|
273
268
|
function resolveInterceptTargetPath(
|
|
274
269
|
interceptTargetPath: string,
|
|
275
270
|
levels: number,
|
|
276
|
-
layoutNode: RouteNode
|
|
277
|
-
currentPath: string
|
|
271
|
+
layoutNode: RouteNode
|
|
278
272
|
): string {
|
|
279
|
-
//
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
let layoutPath = layoutNode.contextKey
|
|
283
|
-
.replace(/^\.\//, '') // Remove leading ./
|
|
284
|
-
.replace(/\/?_layout.*$/, '') // Remove _layout and extension (with optional leading /)
|
|
285
|
-
.replace(/^app\/?/, '') // Remove 'app/' prefix since routes are relative to app dir
|
|
286
|
-
|
|
287
|
-
// Strip route groups like (app), (tabs) since they don't appear in URLs
|
|
288
|
-
layoutPath = stripGroupSegmentsFromPath(layoutPath)
|
|
289
|
-
|
|
290
|
-
// Normalize: empty string or '/' means root
|
|
291
|
-
if (!layoutPath || layoutPath === '/') {
|
|
292
|
-
layoutPath = ''
|
|
293
|
-
}
|
|
273
|
+
// reuse getLayoutPath and strip leading slash for internal resolution
|
|
274
|
+
const fullLayoutPath = getLayoutPath(layoutNode)
|
|
275
|
+
let layoutPath = fullLayoutPath === '/' ? '' : fullLayoutPath.slice(1)
|
|
294
276
|
|
|
295
277
|
if (levels === Infinity) {
|
|
296
278
|
// (...) matches from root - target path is absolute
|
|
@@ -468,13 +450,6 @@ export function isReturningFromIntercept(): boolean {
|
|
|
468
450
|
return returningFromIntercept
|
|
469
451
|
}
|
|
470
452
|
|
|
471
|
-
// Store intercept state info for forward navigation restoration
|
|
472
|
-
interface StoredInterceptState {
|
|
473
|
-
slotName: string
|
|
474
|
-
routeContextKey: string
|
|
475
|
-
params: Record<string, string>
|
|
476
|
-
}
|
|
477
|
-
|
|
478
453
|
// Callback to set slot state - set from Navigator.tsx to avoid circular deps
|
|
479
454
|
let setSlotStateCallback:
|
|
480
455
|
| ((
|
package/src/router/router.ts
CHANGED
|
@@ -475,7 +475,6 @@ export function subscribeToStore(subscriber: () => void) {
|
|
|
475
475
|
}
|
|
476
476
|
}
|
|
477
477
|
|
|
478
|
-
// Subscription functions
|
|
479
478
|
export function subscribeToLoadingState(subscriber: OneRouter.LoadingStateListener) {
|
|
480
479
|
loadingStateSubscribers.add(subscriber)
|
|
481
480
|
return () => {
|
|
@@ -1163,8 +1162,6 @@ export async function linkTo(
|
|
|
1163
1162
|
}, 1000)
|
|
1164
1163
|
}
|
|
1165
1164
|
})
|
|
1166
|
-
|
|
1167
|
-
return
|
|
1168
1165
|
}
|
|
1169
1166
|
|
|
1170
1167
|
const hashes: Record<string, string> = {}
|
package/src/server/oneServe.ts
CHANGED
|
@@ -22,6 +22,19 @@ import { getFetchStaticHtml } from './staticHtmlFetcher'
|
|
|
22
22
|
|
|
23
23
|
const debugRouter = process.env.ONE_DEBUG_ROUTER
|
|
24
24
|
|
|
25
|
+
async function readStaticHtml(htmlPath: string): Promise<string | null> {
|
|
26
|
+
const fetchStaticHtml = getFetchStaticHtml()
|
|
27
|
+
if (fetchStaticHtml) {
|
|
28
|
+
const html = await fetchStaticHtml(htmlPath)
|
|
29
|
+
if (html) return html
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
return await readFile(join('dist/client', htmlPath), 'utf-8')
|
|
33
|
+
} catch {
|
|
34
|
+
return null
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
25
38
|
/**
|
|
26
39
|
* Lazy import functions for route modules.
|
|
27
40
|
* Modules are loaded on-demand when a route is matched, not all upfront.
|
|
@@ -102,6 +115,43 @@ export async function oneServe(
|
|
|
102
115
|
|
|
103
116
|
const apiCJS = oneOptions.build?.api?.outputFormat === 'cjs'
|
|
104
117
|
|
|
118
|
+
// shared helper to import a route module and run its loader
|
|
119
|
+
async function importAndRunLoader(
|
|
120
|
+
routeId: string,
|
|
121
|
+
serverPath: string | undefined,
|
|
122
|
+
lazyKey: string | undefined,
|
|
123
|
+
loaderProps: any
|
|
124
|
+
): Promise<{ loaderData: unknown; routeId: string; isEnoent?: boolean }> {
|
|
125
|
+
if (!serverPath && !lazyKey) {
|
|
126
|
+
return { loaderData: undefined, routeId }
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
const pathToResolve = serverPath || lazyKey || ''
|
|
131
|
+
const resolvedPath = pathToResolve.includes('dist/server')
|
|
132
|
+
? pathToResolve
|
|
133
|
+
: join('./', 'dist/server', pathToResolve)
|
|
134
|
+
|
|
135
|
+
const routeExported = lazyKey
|
|
136
|
+
? options?.lazyRoutes?.pages?.[lazyKey]
|
|
137
|
+
? await options.lazyRoutes.pages[lazyKey]()
|
|
138
|
+
: await import(toAbsolute(resolvedPath))
|
|
139
|
+
: await import(toAbsolute(serverPath!))
|
|
140
|
+
|
|
141
|
+
const loaderData = await routeExported?.loader?.(loaderProps)
|
|
142
|
+
return { loaderData, routeId }
|
|
143
|
+
} catch (err) {
|
|
144
|
+
if (isResponse(err)) {
|
|
145
|
+
throw err
|
|
146
|
+
}
|
|
147
|
+
if ((err as any)?.code === 'ENOENT') {
|
|
148
|
+
return { loaderData: undefined, routeId, isEnoent: true }
|
|
149
|
+
}
|
|
150
|
+
console.error(`[one] Error running loader for ${routeId}:`, err)
|
|
151
|
+
return { loaderData: undefined, routeId }
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
105
155
|
// Lazy load server entry only when needed for SSR
|
|
106
156
|
let render: ((props: RenderAppProps) => any) | null = null
|
|
107
157
|
async function getRender() {
|
|
@@ -211,57 +261,24 @@ export async function oneServe(
|
|
|
211
261
|
}
|
|
212
262
|
|
|
213
263
|
try {
|
|
214
|
-
// helper to import and run a single loader
|
|
215
|
-
async function runLoader(
|
|
216
|
-
routeId: string,
|
|
217
|
-
serverPath: string | undefined,
|
|
218
|
-
lazyKey?: string
|
|
219
|
-
): Promise<{ loaderData: unknown; routeId: string; isEnoent?: boolean }> {
|
|
220
|
-
if (!serverPath && !lazyKey) {
|
|
221
|
-
return { loaderData: undefined, routeId }
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
try {
|
|
225
|
-
// serverPath may already include dist/server if it came from buildInfo.serverJsPath
|
|
226
|
-
const pathToResolve = serverPath || lazyKey || ''
|
|
227
|
-
const resolvedPath = pathToResolve.includes('dist/server')
|
|
228
|
-
? pathToResolve
|
|
229
|
-
: join('./', 'dist/server', pathToResolve)
|
|
230
|
-
|
|
231
|
-
const routeExported = lazyKey
|
|
232
|
-
? options?.lazyRoutes?.pages?.[lazyKey]
|
|
233
|
-
? await options.lazyRoutes.pages[lazyKey]()
|
|
234
|
-
: await import(toAbsolute(resolvedPath))
|
|
235
|
-
: await import(toAbsolute(serverPath!))
|
|
236
|
-
|
|
237
|
-
const loaderData = await routeExported?.loader?.(loaderProps)
|
|
238
|
-
return { loaderData, routeId }
|
|
239
|
-
} catch (err) {
|
|
240
|
-
// if a loader throws a Response (redirect), re-throw it
|
|
241
|
-
if (isResponse(err)) {
|
|
242
|
-
throw err
|
|
243
|
-
}
|
|
244
|
-
if ((err as any)?.code === 'ENOENT') {
|
|
245
|
-
return { loaderData: undefined, routeId, isEnoent: true }
|
|
246
|
-
}
|
|
247
|
-
console.error(`[one] Error running loader for ${routeId}:`, err)
|
|
248
|
-
return { loaderData: undefined, routeId }
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
264
|
// collect layout loaders to run in parallel
|
|
253
265
|
const layoutRoutes = route.layouts || []
|
|
254
266
|
const layoutLoaderPromises = layoutRoutes.map((layout: any) => {
|
|
255
|
-
// layouts may have loaderServerPath set from build, or we can try contextKey
|
|
256
267
|
const serverPath = layout.loaderServerPath || layout.contextKey
|
|
257
|
-
return
|
|
268
|
+
return importAndRunLoader(
|
|
269
|
+
layout.contextKey,
|
|
270
|
+
serverPath,
|
|
271
|
+
layout.contextKey,
|
|
272
|
+
loaderProps
|
|
273
|
+
)
|
|
258
274
|
})
|
|
259
275
|
|
|
260
276
|
// run page loader
|
|
261
|
-
const pageLoaderPromise =
|
|
277
|
+
const pageLoaderPromise = importAndRunLoader(
|
|
262
278
|
route.file,
|
|
263
279
|
buildInfo.serverJsPath,
|
|
264
|
-
route.file
|
|
280
|
+
route.file,
|
|
281
|
+
loaderProps
|
|
265
282
|
)
|
|
266
283
|
|
|
267
284
|
// wait for all loaders in parallel
|
|
@@ -375,43 +392,16 @@ url: ${url}`)
|
|
|
375
392
|
|
|
376
393
|
if (needsSpaShell) {
|
|
377
394
|
try {
|
|
378
|
-
// helper to import and run a single loader
|
|
379
|
-
async function runShellLoader(
|
|
380
|
-
routeId: string,
|
|
381
|
-
serverPath: string | undefined,
|
|
382
|
-
lazyKey?: string
|
|
383
|
-
): Promise<{ loaderData: unknown; routeId: string }> {
|
|
384
|
-
if (!serverPath && !lazyKey) {
|
|
385
|
-
return { loaderData: undefined, routeId }
|
|
386
|
-
}
|
|
387
|
-
try {
|
|
388
|
-
const pathToResolve = serverPath || lazyKey || ''
|
|
389
|
-
const resolvedPath = pathToResolve.includes('dist/server')
|
|
390
|
-
? pathToResolve
|
|
391
|
-
: join('./', 'dist/server', pathToResolve)
|
|
392
|
-
|
|
393
|
-
const routeExported = lazyKey
|
|
394
|
-
? options?.lazyRoutes?.pages?.[lazyKey]
|
|
395
|
-
? await options.lazyRoutes.pages[lazyKey]()
|
|
396
|
-
: await import(toAbsolute(resolvedPath))
|
|
397
|
-
: await import(toAbsolute(serverPath!))
|
|
398
|
-
|
|
399
|
-
const loaderData = await routeExported?.loader?.(loaderProps)
|
|
400
|
-
return { loaderData, routeId }
|
|
401
|
-
} catch (err) {
|
|
402
|
-
if (isResponse(err)) {
|
|
403
|
-
throw err
|
|
404
|
-
}
|
|
405
|
-
console.error(`[one] Error running shell loader for ${routeId}:`, err)
|
|
406
|
-
return { loaderData: undefined, routeId }
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
|
|
410
395
|
// run layout loaders only (page content is client-rendered)
|
|
411
396
|
const layoutResults = await Promise.all(
|
|
412
397
|
layoutRoutes.map((layout: any) => {
|
|
413
398
|
const serverPath = layout.loaderServerPath || layout.contextKey
|
|
414
|
-
return
|
|
399
|
+
return importAndRunLoader(
|
|
400
|
+
layout.contextKey,
|
|
401
|
+
serverPath,
|
|
402
|
+
layout.contextKey,
|
|
403
|
+
loaderProps
|
|
404
|
+
)
|
|
415
405
|
})
|
|
416
406
|
)
|
|
417
407
|
|
|
@@ -477,22 +467,7 @@ url: ${url}`)
|
|
|
477
467
|
: routeMap[url.pathname] || routeMap[buildInfo?.cleanPath]
|
|
478
468
|
|
|
479
469
|
if (htmlPath) {
|
|
480
|
-
|
|
481
|
-
const fetchStaticHtml = getFetchStaticHtml()
|
|
482
|
-
let html: string | null = null
|
|
483
|
-
|
|
484
|
-
if (fetchStaticHtml) {
|
|
485
|
-
html = await fetchStaticHtml(htmlPath)
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
if (!html) {
|
|
489
|
-
// Fall back to filesystem (Node.js)
|
|
490
|
-
try {
|
|
491
|
-
html = await readFile(join('dist/client', htmlPath), 'utf-8')
|
|
492
|
-
} catch {
|
|
493
|
-
// File not found
|
|
494
|
-
}
|
|
495
|
-
}
|
|
470
|
+
const html = await readStaticHtml(htmlPath)
|
|
496
471
|
|
|
497
472
|
if (html) {
|
|
498
473
|
const headers = new Headers()
|
|
@@ -511,23 +486,7 @@ url: ${url}`)
|
|
|
511
486
|
const notFoundHtmlPath = routeMap[notFoundRoute]
|
|
512
487
|
|
|
513
488
|
if (notFoundHtmlPath) {
|
|
514
|
-
const
|
|
515
|
-
let notFoundHtml: string | null = null
|
|
516
|
-
|
|
517
|
-
if (fetchStaticHtml) {
|
|
518
|
-
notFoundHtml = await fetchStaticHtml(notFoundHtmlPath)
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
if (!notFoundHtml) {
|
|
522
|
-
try {
|
|
523
|
-
notFoundHtml = await readFile(
|
|
524
|
-
join('dist/client', notFoundHtmlPath),
|
|
525
|
-
'utf-8'
|
|
526
|
-
)
|
|
527
|
-
} catch {
|
|
528
|
-
// File not found
|
|
529
|
-
}
|
|
530
|
-
}
|
|
489
|
+
const notFoundHtml = await readStaticHtml(notFoundHtmlPath)
|
|
531
490
|
|
|
532
491
|
if (notFoundHtml) {
|
|
533
492
|
// inject 404 marker so client knows this is a 404 response
|
package/src/useLoader.ts
CHANGED
|
@@ -398,8 +398,7 @@ export function useLoaderState<
|
|
|
398
398
|
if (
|
|
399
399
|
!loaderStateEntry.data &&
|
|
400
400
|
!loaderStateEntry.promise &&
|
|
401
|
-
!loaderStateEntry.hasLoadedOnce
|
|
402
|
-
loader
|
|
401
|
+
!loaderStateEntry.hasLoadedOnce
|
|
403
402
|
) {
|
|
404
403
|
// check for already-resolved preloaded data first (synchronous)
|
|
405
404
|
// use != null to also exclude null values (which indicate preload failures)
|
|
@@ -641,33 +640,24 @@ export function useLoaderState<
|
|
|
641
640
|
}
|
|
642
641
|
}
|
|
643
642
|
|
|
644
|
-
// handle errors and suspension
|
|
645
|
-
if (
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
throw loaderStateEntry.error
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
// only throw promise for suspension on initial load
|
|
652
|
-
if (
|
|
653
|
-
loaderStateEntry.data === undefined &&
|
|
654
|
-
loaderStateEntry.promise &&
|
|
655
|
-
!loaderStateEntry.hasLoadedOnce
|
|
656
|
-
) {
|
|
657
|
-
throw loaderStateEntry.promise
|
|
658
|
-
}
|
|
643
|
+
// handle errors and suspension (only on initial load)
|
|
644
|
+
if (loaderStateEntry.error && !loaderStateEntry.hasLoadedOnce) {
|
|
645
|
+
throw loaderStateEntry.error
|
|
646
|
+
}
|
|
659
647
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
return {
|
|
667
|
-
refetch,
|
|
668
|
-
state: loaderStateEntry.state,
|
|
669
|
-
} as any
|
|
648
|
+
if (
|
|
649
|
+
loaderStateEntry.data === undefined &&
|
|
650
|
+
loaderStateEntry.promise &&
|
|
651
|
+
!loaderStateEntry.hasLoadedOnce
|
|
652
|
+
) {
|
|
653
|
+
throw loaderStateEntry.promise
|
|
670
654
|
}
|
|
655
|
+
|
|
656
|
+
return {
|
|
657
|
+
data: loaderStateEntry.data,
|
|
658
|
+
refetch,
|
|
659
|
+
state: loaderStateEntry.state,
|
|
660
|
+
} as any
|
|
671
661
|
}
|
|
672
662
|
|
|
673
663
|
/**
|
package/src/utils/redirect.ts
CHANGED
|
@@ -6,7 +6,7 @@ export const redirect = (
|
|
|
6
6
|
path: '__branded__' extends keyof OneRouter.Href ? string : OneRouter.Href,
|
|
7
7
|
status?: number
|
|
8
8
|
) => {
|
|
9
|
-
if (process.env.VITE_ENVIRONMENT
|
|
9
|
+
if (process.env.VITE_ENVIRONMENT !== 'ssr') {
|
|
10
10
|
router.navigate(path)
|
|
11
11
|
return
|
|
12
12
|
}
|
package/src/views/Navigator.tsx
CHANGED
package/src/vite/one.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from '@vxrn/vite-plugin-metro'
|
|
8
8
|
import events from 'node:events'
|
|
9
9
|
import path from 'node:path'
|
|
10
|
-
import {
|
|
10
|
+
import { type Plugin, type PluginOption } from 'vite'
|
|
11
11
|
import tsconfigPaths from 'vite-tsconfig-paths'
|
|
12
12
|
import { autoDepOptimizePlugin, getOptionsFilled, loadEnv } from 'vxrn'
|
|
13
13
|
import vxrnVitePlugin from 'vxrn/vite-plugin'
|
|
@@ -252,8 +252,6 @@ export function one(options: One.PluginOptions = {}): PluginOption {
|
|
|
252
252
|
enforce: 'pre',
|
|
253
253
|
|
|
254
254
|
config() {
|
|
255
|
-
// const forkPath = dirname(resolvePath('one'))
|
|
256
|
-
|
|
257
255
|
let tslibLitePath = ''
|
|
258
256
|
|
|
259
257
|
try {
|
|
@@ -279,22 +277,6 @@ export function one(options: One.PluginOptions = {}): PluginOption {
|
|
|
279
277
|
tslib: tslibLitePath,
|
|
280
278
|
}),
|
|
281
279
|
},
|
|
282
|
-
|
|
283
|
-
// [
|
|
284
|
-
// {
|
|
285
|
-
// find: /tslib/,
|
|
286
|
-
// replacement: resolvePath('@vxrn/tslib-lite'),
|
|
287
|
-
// },
|
|
288
|
-
// // not working but would save ~30Kb stat
|
|
289
|
-
// // {
|
|
290
|
-
// // find: /@react-navigation\/core.*\/getStateFromPath/,
|
|
291
|
-
// // replacement: join(forkPath, 'fork', 'getStateFromPath.mjs'),
|
|
292
|
-
// // },
|
|
293
|
-
// // {
|
|
294
|
-
// // find: /@react-navigation\/core.*\/getPathFromState/,
|
|
295
|
-
// // replacement: join(forkPath, 'fork', 'getPathFromState.mjs'),
|
|
296
|
-
// // },
|
|
297
|
-
// ],
|
|
298
280
|
},
|
|
299
281
|
}
|
|
300
282
|
},
|
|
@@ -526,88 +508,8 @@ export function one(options: One.PluginOptions = {}): PluginOption {
|
|
|
526
508
|
},
|
|
527
509
|
] satisfies Plugin[]
|
|
528
510
|
|
|
529
|
-
// leaving this as a good example of an option that loads a library conditionally
|
|
530
|
-
// // react scan
|
|
531
|
-
// const scan = options.react?.scan
|
|
532
|
-
|
|
533
|
-
// const reactScanPlugin = {
|
|
534
|
-
// name: `one:react-scan`,
|
|
535
|
-
// config() {
|
|
536
|
-
// return reactScanConfig
|
|
537
|
-
// },
|
|
538
|
-
// }
|
|
539
|
-
// devAndProdPlugins.push(reactScanPlugin)
|
|
540
|
-
|
|
541
|
-
// // do it here because it gets called a few times
|
|
542
|
-
// const reactScanConfig = ((): UserConfig => {
|
|
543
|
-
// const stringify = (obj: Object) => JSON.stringify(JSON.stringify(obj))
|
|
544
|
-
|
|
545
|
-
// const configs = {
|
|
546
|
-
// disabled: {
|
|
547
|
-
// define: {
|
|
548
|
-
// 'process.env.ONE_ENABLE_REACT_SCAN': '""',
|
|
549
|
-
// },
|
|
550
|
-
// },
|
|
551
|
-
// enabled: {
|
|
552
|
-
// define: {
|
|
553
|
-
// 'process.env.ONE_ENABLE_REACT_SCAN': stringify({
|
|
554
|
-
// enabled: true,
|
|
555
|
-
// animationSpeed: 'slow',
|
|
556
|
-
// showToolbar: false,
|
|
557
|
-
// }),
|
|
558
|
-
// },
|
|
559
|
-
// },
|
|
560
|
-
// } satisfies Record<string, UserConfig>
|
|
561
|
-
|
|
562
|
-
// const getConfigFor = (platform: 'ios' | 'android' | 'client'): UserConfig => {
|
|
563
|
-
// if (process.env.NODE_ENV === 'production') {
|
|
564
|
-
// return configs.disabled
|
|
565
|
-
// }
|
|
566
|
-
// if (!scan) {
|
|
567
|
-
// return configs.disabled
|
|
568
|
-
// }
|
|
569
|
-
// if (scan === true) {
|
|
570
|
-
// return configs.enabled
|
|
571
|
-
// }
|
|
572
|
-
// if (typeof scan === 'string') {
|
|
573
|
-
// if (scan === 'native' && platform === 'client') {
|
|
574
|
-
// return configs.disabled
|
|
575
|
-
// }
|
|
576
|
-
// if (scan === 'web' && platform !== 'client') {
|
|
577
|
-
// return configs.disabled
|
|
578
|
-
// }
|
|
579
|
-
// return configs.enabled
|
|
580
|
-
// }
|
|
581
|
-
|
|
582
|
-
// const defaultConfig = scan.options || configs.enabled
|
|
583
|
-
// const perPlatformConfig =
|
|
584
|
-
// platform === 'ios' || platform === 'android' ? scan.native : scan.web
|
|
585
|
-
|
|
586
|
-
// return {
|
|
587
|
-
// define: {
|
|
588
|
-
// 'process.env.ONE_ENABLE_REACT_SCAN': stringify({
|
|
589
|
-
// ...defaultConfig,
|
|
590
|
-
// ...perPlatformConfig,
|
|
591
|
-
// }),
|
|
592
|
-
// },
|
|
593
|
-
// }
|
|
594
|
-
// }
|
|
595
|
-
|
|
596
|
-
// return {
|
|
597
|
-
// environments: {
|
|
598
|
-
// client: getConfigFor('client'),
|
|
599
|
-
// ios: getConfigFor('ios'),
|
|
600
|
-
// android: getConfigFor('android'),
|
|
601
|
-
// },
|
|
602
|
-
// }
|
|
603
|
-
// })()
|
|
604
|
-
|
|
605
511
|
// TODO move to single config and through environments
|
|
606
|
-
const nativeWebDevAndProdPlugsin: Plugin[] = [
|
|
607
|
-
clientTreeShakePlugin(),
|
|
608
|
-
//
|
|
609
|
-
// reactScanPlugin
|
|
610
|
-
]
|
|
512
|
+
const nativeWebDevAndProdPlugsin: Plugin[] = [clientTreeShakePlugin()]
|
|
611
513
|
|
|
612
514
|
// TODO make this passed into vxrn through real API
|
|
613
515
|
globalThis.__vxrnAddNativePlugins = nativeWebDevAndProdPlugsin
|