kiru 0.54.0-preview.1 → 0.54.1
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/components/derive.d.ts +1 -1
- package/dist/components/derive.d.ts.map +1 -1
- package/dist/components/derive.js +2 -3
- package/dist/components/derive.js.map +1 -1
- package/dist/components/memo.d.ts +1 -3
- package/dist/components/memo.d.ts.map +1 -1
- package/dist/components/memo.js +2 -2
- package/dist/components/memo.js.map +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +1 -23
- package/dist/context.js.map +1 -1
- package/dist/dom.d.ts.map +1 -1
- package/dist/dom.js +111 -78
- package/dist/dom.js.map +1 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +2 -4
- package/dist/error.js.map +1 -1
- package/dist/form/index.d.ts.map +1 -1
- package/dist/form/index.js +6 -10
- package/dist/form/index.js.map +1 -1
- package/dist/globals.d.ts +1 -1
- package/dist/globals.d.ts.map +1 -1
- package/dist/globals.js.map +1 -1
- package/dist/hmr.d.ts +1 -0
- package/dist/hmr.d.ts.map +1 -1
- package/dist/hmr.js +11 -3
- package/dist/hmr.js.map +1 -1
- package/dist/hooks/useEffectEvent.d.ts.map +1 -1
- package/dist/hooks/useEffectEvent.js.map +1 -1
- package/dist/hooks/usePromise.d.ts +1 -2
- package/dist/hooks/usePromise.d.ts.map +1 -1
- package/dist/hooks/usePromise.js +62 -31
- package/dist/hooks/usePromise.js.map +1 -1
- package/dist/hooks/utils.d.ts.map +1 -1
- package/dist/hooks/utils.js +10 -10
- package/dist/hooks/utils.js.map +1 -1
- package/dist/hydration.d.ts +6 -13
- package/dist/hydration.d.ts.map +1 -1
- package/dist/hydration.js +20 -50
- package/dist/hydration.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/reconciler.d.ts.map +1 -1
- package/dist/reconciler.js +3 -6
- package/dist/reconciler.js.map +1 -1
- package/dist/recursiveRender.d.ts.map +1 -1
- package/dist/recursiveRender.js +9 -8
- package/dist/recursiveRender.js.map +1 -1
- package/dist/renderToString.d.ts.map +1 -1
- package/dist/renderToString.js.map +1 -1
- package/dist/router/client/index.d.ts +2 -4
- package/dist/router/client/index.d.ts.map +1 -1
- package/dist/router/client/index.js +13 -59
- package/dist/router/client/index.js.map +1 -1
- package/dist/router/context.d.ts +5 -2
- package/dist/router/context.d.ts.map +1 -1
- package/dist/router/context.js +1 -5
- package/dist/router/context.js.map +1 -1
- package/dist/router/fileRouter.d.ts.map +1 -1
- package/dist/router/fileRouter.js +2 -4
- package/dist/router/fileRouter.js.map +1 -1
- package/dist/router/fileRouterController.d.ts +2 -2
- package/dist/router/fileRouterController.d.ts.map +1 -1
- package/dist/router/fileRouterController.js +135 -214
- package/dist/router/fileRouterController.js.map +1 -1
- package/dist/router/globals.d.ts +0 -3
- package/dist/router/globals.d.ts.map +1 -1
- package/dist/router/globals.js +0 -3
- package/dist/router/globals.js.map +1 -1
- package/dist/router/head.d.ts.map +1 -1
- package/dist/router/head.js +7 -5
- package/dist/router/head.js.map +1 -1
- package/dist/router/index.d.ts +1 -2
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +1 -2
- package/dist/router/index.js.map +1 -1
- package/dist/router/link.js +3 -3
- package/dist/router/link.js.map +1 -1
- package/dist/router/{ssg → server}/index.d.ts +4 -4
- package/dist/router/server/index.d.ts.map +1 -0
- package/dist/router/{ssg → server}/index.js +7 -9
- package/dist/router/server/index.js.map +1 -0
- package/dist/router/types.d.ts +16 -42
- package/dist/router/types.d.ts.map +1 -1
- package/dist/router/types.internal.d.ts +0 -4
- package/dist/router/types.internal.d.ts.map +1 -1
- package/dist/router/utils/index.d.ts +3 -8
- package/dist/router/utils/index.d.ts.map +1 -1
- package/dist/router/utils/index.js +8 -40
- package/dist/router/utils/index.js.map +1 -1
- package/dist/scheduler.d.ts +3 -14
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +64 -56
- package/dist/scheduler.js.map +1 -1
- package/dist/signals/base.d.ts +0 -2
- package/dist/signals/base.d.ts.map +1 -1
- package/dist/signals/base.js +0 -6
- package/dist/signals/base.js.map +1 -1
- package/dist/signals/computed.d.ts +3 -0
- package/dist/signals/computed.d.ts.map +1 -1
- package/dist/signals/computed.js +29 -20
- package/dist/signals/computed.js.map +1 -1
- package/dist/signals/for.d.ts +3 -3
- package/dist/signals/for.d.ts.map +1 -1
- package/dist/signals/for.js +2 -1
- package/dist/signals/for.js.map +1 -1
- package/dist/signals/utils.d.ts.map +1 -1
- package/dist/signals/utils.js +2 -1
- package/dist/signals/utils.js.map +1 -1
- package/dist/signals/watch.d.ts.map +1 -1
- package/dist/signals/watch.js +18 -22
- package/dist/signals/watch.js.map +1 -1
- package/dist/ssr/client.d.ts +1 -1
- package/dist/ssr/client.d.ts.map +1 -1
- package/dist/ssr/client.js +0 -2
- package/dist/ssr/client.js.map +1 -1
- package/dist/ssr/server.d.ts +3 -9
- package/dist/ssr/server.d.ts.map +1 -1
- package/dist/ssr/server.js +30 -37
- package/dist/ssr/server.js.map +1 -1
- package/dist/types.d.ts +0 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/types.dom.d.ts +3 -3
- package/dist/types.dom.d.ts.map +1 -1
- package/dist/utils/format.d.ts +1 -2
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js +1 -4
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/promise.d.ts +0 -2
- package/dist/utils/promise.d.ts.map +1 -1
- package/dist/utils/promise.js +1 -45
- package/dist/utils/promise.js.map +1 -1
- package/dist/utils/runtime.d.ts +3 -2
- package/dist/utils/runtime.d.ts.map +1 -1
- package/dist/utils/runtime.js +5 -2
- package/dist/utils/runtime.js.map +1 -1
- package/dist/utils/vdom.d.ts.map +1 -1
- package/dist/utils/vdom.js +2 -2
- package/dist/utils/vdom.js.map +1 -1
- package/package.json +4 -8
- package/src/components/derive.ts +3 -5
- package/src/components/memo.ts +3 -11
- package/src/context.ts +1 -24
- package/src/dom.ts +146 -101
- package/src/error.ts +2 -4
- package/src/form/index.ts +6 -9
- package/src/globals.ts +1 -1
- package/src/hmr.ts +14 -5
- package/src/hooks/useEffectEvent.ts +0 -1
- package/src/hooks/usePromise.ts +77 -58
- package/src/hooks/utils.ts +12 -12
- package/src/hydration.ts +21 -57
- package/src/index.ts +1 -1
- package/src/reconciler.ts +2 -6
- package/src/recursiveRender.ts +10 -9
- package/src/renderToString.ts +0 -1
- package/src/router/client/index.ts +16 -114
- package/src/router/context.ts +6 -7
- package/src/router/fileRouter.ts +2 -6
- package/src/router/fileRouterController.ts +161 -324
- package/src/router/globals.ts +0 -4
- package/src/router/head.ts +7 -5
- package/src/router/index.ts +1 -12
- package/src/router/link.ts +3 -3
- package/src/router/{ssg → server}/index.ts +13 -18
- package/src/router/types.internal.ts +0 -5
- package/src/router/types.ts +16 -53
- package/src/router/utils/index.ts +16 -79
- package/src/scheduler.ts +85 -89
- package/src/signals/base.ts +0 -8
- package/src/signals/computed.ts +30 -18
- package/src/signals/for.ts +15 -10
- package/src/signals/utils.ts +2 -1
- package/src/signals/watch.ts +27 -22
- package/src/ssr/client.ts +1 -4
- package/src/ssr/server.ts +34 -59
- package/src/types.dom.ts +4 -5
- package/src/types.ts +0 -10
- package/src/utils/format.ts +0 -5
- package/src/utils/index.ts +1 -1
- package/src/utils/promise.ts +1 -70
- package/src/utils/runtime.ts +6 -2
- package/src/utils/vdom.ts +2 -7
- package/dist/router/constants.d.ts +0 -2
- package/dist/router/constants.d.ts.map +0 -1
- package/dist/router/constants.js +0 -2
- package/dist/router/constants.js.map +0 -1
- package/dist/router/guard.d.ts +0 -17
- package/dist/router/guard.d.ts.map +0 -1
- package/dist/router/guard.js +0 -45
- package/dist/router/guard.js.map +0 -1
- package/dist/router/ssg/index.d.ts.map +0 -1
- package/dist/router/ssg/index.js.map +0 -1
- package/dist/router/ssr/index.d.ts +0 -20
- package/dist/router/ssr/index.d.ts.map +0 -1
- package/dist/router/ssr/index.js +0 -163
- package/dist/router/ssr/index.js.map +0 -1
- package/src/router/constants.ts +0 -1
- package/src/router/guard.ts +0 -72
- package/src/router/ssr/index.ts +0 -252
|
@@ -2,15 +2,9 @@ import { Signal } from "../signals/base.js"
|
|
|
2
2
|
import { watch } from "../signals/watch.js"
|
|
3
3
|
import { __DEV__ } from "../env.js"
|
|
4
4
|
import { flushSync, nextIdle } from "../scheduler.js"
|
|
5
|
-
import { toArray } from "../utils/format.js"
|
|
6
5
|
import { ReloadOptions, type FileRouterContextType } from "./context.js"
|
|
7
6
|
import { FileRouterDataLoadError } from "./errors.js"
|
|
8
|
-
import {
|
|
9
|
-
fileRouterInstance,
|
|
10
|
-
fileRouterRoute,
|
|
11
|
-
requestContext,
|
|
12
|
-
routerCache,
|
|
13
|
-
} from "./globals.js"
|
|
7
|
+
import { fileRouterInstance, fileRouterRoute, routerCache } from "./globals.js"
|
|
14
8
|
import type {
|
|
15
9
|
FileRouterConfig,
|
|
16
10
|
PageConfig,
|
|
@@ -23,22 +17,17 @@ import type {
|
|
|
23
17
|
CurrentPage,
|
|
24
18
|
DevtoolsInterface,
|
|
25
19
|
FormattedViteImportMap,
|
|
26
|
-
GuardModule,
|
|
27
20
|
PageModule,
|
|
28
21
|
ViteImportMap,
|
|
29
22
|
} from "./types.internal.js"
|
|
30
23
|
import {
|
|
31
24
|
formatViteImportMap,
|
|
32
|
-
|
|
25
|
+
matchLayouts,
|
|
33
26
|
matchRoute,
|
|
34
27
|
match404Route,
|
|
35
28
|
normalizePrefixPath,
|
|
36
29
|
parseQuery,
|
|
37
30
|
wrapWithLayouts,
|
|
38
|
-
runAfterEachGuards,
|
|
39
|
-
runBeforeEachGuards,
|
|
40
|
-
runBeforeEnterHooks,
|
|
41
|
-
runBeforeLeaveHooks,
|
|
42
31
|
} from "./utils/index.js"
|
|
43
32
|
import { RouterCache, type CacheKey } from "./cache.js"
|
|
44
33
|
import { scrollStack } from "./scrollStack.js"
|
|
@@ -47,19 +36,6 @@ interface PageConfigWithLoader<T = unknown> extends PageConfig {
|
|
|
47
36
|
loader: PageDataLoaderConfig<T>
|
|
48
37
|
}
|
|
49
38
|
|
|
50
|
-
interface LoadRouteOptions {
|
|
51
|
-
path?: string
|
|
52
|
-
transition?: boolean
|
|
53
|
-
isStatic404?: boolean
|
|
54
|
-
onPaint?: () => void
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
let transitionId = 0
|
|
58
|
-
let currentTransition = null as null | {
|
|
59
|
-
transition: ViewTransition
|
|
60
|
-
id: number
|
|
61
|
-
}
|
|
62
|
-
|
|
63
39
|
export class FileRouterController {
|
|
64
40
|
public contextValue: FileRouterContextType
|
|
65
41
|
public devtools?: DevtoolsInterface
|
|
@@ -79,9 +55,9 @@ export class FileRouterController {
|
|
|
79
55
|
private historyIndex: number
|
|
80
56
|
private layouts: FormattedViteImportMap
|
|
81
57
|
private pages: FormattedViteImportMap<PageModule>
|
|
82
|
-
private guards: FormattedViteImportMap<GuardModule>
|
|
83
58
|
private pageRouteToConfig?: Map<string, PageConfig>
|
|
84
59
|
private state: RouterState
|
|
60
|
+
private baseUrl = "/"
|
|
85
61
|
|
|
86
62
|
constructor() {
|
|
87
63
|
routerCache.current ??= new RouterCache()
|
|
@@ -93,7 +69,6 @@ export class FileRouterController {
|
|
|
93
69
|
this.historyIndex = 0
|
|
94
70
|
this.layouts = {}
|
|
95
71
|
this.pages = {}
|
|
96
|
-
this.guards = {}
|
|
97
72
|
this.state = {
|
|
98
73
|
pathname: window.location.pathname,
|
|
99
74
|
hash: window.location.hash,
|
|
@@ -101,27 +76,7 @@ export class FileRouterController {
|
|
|
101
76
|
query: {},
|
|
102
77
|
signal: this.abortController.signal,
|
|
103
78
|
}
|
|
104
|
-
|
|
105
|
-
this.contextValue = {
|
|
106
|
-
invalidate: async (...paths: string[]) => {
|
|
107
|
-
if (this.invalidate(...paths)) {
|
|
108
|
-
return this.loadRoute()
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
get state() {
|
|
112
|
-
return { ...__this.state }
|
|
113
|
-
},
|
|
114
|
-
navigate: this.navigate.bind(this),
|
|
115
|
-
prefetchRouteModules: this.prefetchRouteModules.bind(this),
|
|
116
|
-
reload: async (options?: ReloadOptions) => {
|
|
117
|
-
if (options?.invalidate ?? true) {
|
|
118
|
-
this.invalidate(this.state.pathname)
|
|
119
|
-
}
|
|
120
|
-
return this.loadRoute({ transition: options?.transition })
|
|
121
|
-
},
|
|
122
|
-
setQuery: this.setQuery.bind(this),
|
|
123
|
-
setHash: this.setHash.bind(this),
|
|
124
|
-
}
|
|
79
|
+
this.contextValue = this.createContextValue()
|
|
125
80
|
if (__DEV__) {
|
|
126
81
|
this.filePathToPageRoute = new Map()
|
|
127
82
|
this.pageRouteToConfig = new Map()
|
|
@@ -138,11 +93,12 @@ export class FileRouterController {
|
|
|
138
93
|
if (curPage?.route === existing.route && loader) {
|
|
139
94
|
const p = this.currentPageProps.value
|
|
140
95
|
const transition =
|
|
141
|
-
(
|
|
96
|
+
(loader.mode !== "static" && loader.transition) ??
|
|
97
|
+
this.enableTransitions
|
|
142
98
|
|
|
143
99
|
// Check cache first if caching is enabled
|
|
144
100
|
let cachedData = null
|
|
145
|
-
if (
|
|
101
|
+
if (loader.mode !== "static" && loader.cache) {
|
|
146
102
|
const cacheKey: CacheKey = {
|
|
147
103
|
path: this.state.pathname,
|
|
148
104
|
params: this.state.params,
|
|
@@ -159,11 +115,9 @@ export class FileRouterController {
|
|
|
159
115
|
error: null,
|
|
160
116
|
loading: false,
|
|
161
117
|
}
|
|
162
|
-
handleStateTransition(
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
() => (this.currentPageProps.value = props)
|
|
166
|
-
)
|
|
118
|
+
handleStateTransition(this.state.signal, transition, () => {
|
|
119
|
+
this.currentPageProps.value = props
|
|
120
|
+
})
|
|
167
121
|
} else {
|
|
168
122
|
// No cached data - show loading state and load data
|
|
169
123
|
const props = {
|
|
@@ -172,14 +126,13 @@ export class FileRouterController {
|
|
|
172
126
|
data: null,
|
|
173
127
|
error: null,
|
|
174
128
|
}
|
|
175
|
-
handleStateTransition(
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
() => (this.currentPageProps.value = props)
|
|
179
|
-
)
|
|
129
|
+
handleStateTransition(this.state.signal, transition, () => {
|
|
130
|
+
this.currentPageProps.value = props
|
|
131
|
+
})
|
|
180
132
|
|
|
181
133
|
this.loadRouteData(
|
|
182
134
|
config as PageConfigWithLoader,
|
|
135
|
+
props,
|
|
183
136
|
this.state,
|
|
184
137
|
transition
|
|
185
138
|
)
|
|
@@ -215,7 +168,6 @@ export class FileRouterController {
|
|
|
215
168
|
const {
|
|
216
169
|
pages,
|
|
217
170
|
layouts,
|
|
218
|
-
guards,
|
|
219
171
|
dir = "/pages",
|
|
220
172
|
baseUrl = "/",
|
|
221
173
|
transition,
|
|
@@ -226,39 +178,14 @@ export class FileRouterController {
|
|
|
226
178
|
normalizePrefixPath(dir),
|
|
227
179
|
normalizePrefixPath(baseUrl),
|
|
228
180
|
]
|
|
181
|
+
this.baseUrl = normalizedBaseUrl.slice(0, -1)
|
|
229
182
|
|
|
230
|
-
if (
|
|
231
|
-
this.pages = formatViteImportMap(
|
|
232
|
-
pages as ViteImportMap,
|
|
233
|
-
normalizedDir,
|
|
234
|
-
normalizedBaseUrl
|
|
235
|
-
)
|
|
236
|
-
|
|
237
|
-
this.layouts = formatViteImportMap(
|
|
238
|
-
layouts as ViteImportMap,
|
|
239
|
-
normalizedDir,
|
|
240
|
-
normalizedBaseUrl
|
|
241
|
-
)
|
|
242
|
-
this.guards = !guards
|
|
243
|
-
? {}
|
|
244
|
-
: (formatViteImportMap(
|
|
245
|
-
guards as ViteImportMap,
|
|
246
|
-
normalizedDir,
|
|
247
|
-
normalizedBaseUrl
|
|
248
|
-
) as unknown as FormattedViteImportMap<GuardModule>)
|
|
249
|
-
|
|
250
|
-
if (__DEV__) {
|
|
251
|
-
validateRoutes(this.pages)
|
|
252
|
-
}
|
|
253
|
-
this.loadRoute()
|
|
254
|
-
} else {
|
|
183
|
+
if (preloaded) {
|
|
255
184
|
const {
|
|
256
185
|
pages,
|
|
257
186
|
layouts,
|
|
258
|
-
guards,
|
|
259
187
|
page,
|
|
260
188
|
pageProps,
|
|
261
|
-
pagePropsPromise,
|
|
262
189
|
pageLayouts,
|
|
263
190
|
route,
|
|
264
191
|
params,
|
|
@@ -281,49 +208,57 @@ export class FileRouterController {
|
|
|
281
208
|
this.currentLayouts.value = pageLayouts.map((l) => l.default)
|
|
282
209
|
this.pages = pages
|
|
283
210
|
this.layouts = layouts
|
|
284
|
-
this.guards = (guards ??
|
|
285
|
-
{}) as unknown as FormattedViteImportMap<GuardModule>
|
|
286
211
|
if (__DEV__) {
|
|
287
|
-
validateRoutes(this.pages)
|
|
288
212
|
if (page.config) {
|
|
289
213
|
this.dev_onPageConfigDefined!(route, page.config)
|
|
290
214
|
}
|
|
291
215
|
}
|
|
292
|
-
|
|
216
|
+
if (__DEV__) {
|
|
217
|
+
validateRoutes(this.pages)
|
|
218
|
+
}
|
|
293
219
|
const loader = page.config?.loader
|
|
294
|
-
|
|
295
|
-
(!loader?.static && loader?.transition) ?? this.enableTransitions
|
|
296
|
-
|
|
297
|
-
if (loader && pagePropsPromise) {
|
|
298
|
-
const prevState = this.state
|
|
299
|
-
pagePropsPromise.then(({ data, error }) => {
|
|
300
|
-
if (this.state !== prevState) return
|
|
301
|
-
|
|
302
|
-
handleStateTransition(
|
|
303
|
-
transition,
|
|
304
|
-
transitionId,
|
|
305
|
-
() =>
|
|
306
|
-
(this.currentPageProps.value = { loading: false, data, error })
|
|
307
|
-
)
|
|
308
|
-
})
|
|
309
|
-
} else if (
|
|
220
|
+
if (
|
|
310
221
|
loader &&
|
|
311
|
-
((
|
|
222
|
+
((loader.mode !== "static" && pageProps.loading === true) || __DEV__)
|
|
312
223
|
) {
|
|
313
224
|
if (cacheData === null) {
|
|
314
|
-
this.loadRouteData(
|
|
225
|
+
this.loadRouteData(
|
|
226
|
+
page.config as PageConfigWithLoader,
|
|
227
|
+
pageProps,
|
|
228
|
+
this.state
|
|
229
|
+
)
|
|
315
230
|
} else {
|
|
316
231
|
nextIdle(() => {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
232
|
+
const props = {
|
|
233
|
+
...pageProps,
|
|
234
|
+
data: cacheData.value,
|
|
235
|
+
error: null,
|
|
236
|
+
loading: false,
|
|
237
|
+
}
|
|
238
|
+
// @ts-ignore
|
|
239
|
+
const transition = loader.transition ?? this.enableTransitions
|
|
240
|
+
handleStateTransition(this.state.signal, transition, () => {
|
|
241
|
+
this.currentPageProps.value = props
|
|
323
242
|
})
|
|
324
243
|
})
|
|
325
244
|
}
|
|
326
245
|
}
|
|
246
|
+
} else {
|
|
247
|
+
this.pages = formatViteImportMap(
|
|
248
|
+
pages as ViteImportMap,
|
|
249
|
+
normalizedDir,
|
|
250
|
+
normalizedBaseUrl
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
this.layouts = formatViteImportMap(
|
|
254
|
+
layouts as ViteImportMap,
|
|
255
|
+
normalizedDir,
|
|
256
|
+
normalizedBaseUrl
|
|
257
|
+
)
|
|
258
|
+
if (__DEV__) {
|
|
259
|
+
validateRoutes(this.pages)
|
|
260
|
+
}
|
|
261
|
+
this.loadRoute()
|
|
327
262
|
}
|
|
328
263
|
|
|
329
264
|
window.history.scrollRestoration = "manual"
|
|
@@ -362,74 +297,22 @@ export class FileRouterController {
|
|
|
362
297
|
window.history.scrollRestoration = "auto"
|
|
363
298
|
})
|
|
364
299
|
|
|
365
|
-
let ignorePopState = false
|
|
366
|
-
|
|
367
300
|
window.addEventListener("popstate", (e) => {
|
|
368
301
|
e.preventDefault()
|
|
369
|
-
|
|
370
|
-
if (
|
|
371
|
-
!ignorePopState &&
|
|
372
|
-
this.onBeforeLeave(window.location.pathname) === false
|
|
373
|
-
) {
|
|
374
|
-
ignorePopState = true
|
|
375
|
-
if (e.state !== null) {
|
|
376
|
-
if (e.state.index > this.historyIndex) {
|
|
377
|
-
window.history.go(-1)
|
|
378
|
-
} else if (e.state.index < this.historyIndex) {
|
|
379
|
-
window.history.go(1)
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
return
|
|
383
|
-
}
|
|
384
|
-
if (ignorePopState) {
|
|
385
|
-
ignorePopState = false
|
|
386
|
-
return
|
|
387
|
-
}
|
|
388
|
-
|
|
389
302
|
scrollStack.replace(this.historyIndex, window.scrollX, window.scrollY)
|
|
390
303
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
let onPaint
|
|
394
|
-
if (e.state != null) {
|
|
395
|
-
onPaint = () => {
|
|
304
|
+
this.loadRoute().then(() => {
|
|
305
|
+
if (e.state != null) {
|
|
396
306
|
this.historyIndex = e.state.index
|
|
397
307
|
const offset = scrollStack.getItem(e.state.index)
|
|
398
308
|
if (offset !== undefined) {
|
|
399
309
|
window.scrollTo(...offset)
|
|
400
310
|
}
|
|
401
311
|
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
this.loadRoute({ onPaint })
|
|
312
|
+
})
|
|
405
313
|
})
|
|
406
314
|
}
|
|
407
315
|
|
|
408
|
-
private onBeforeLeave(to: string) {
|
|
409
|
-
const currentPage = this.currentPage.peek()
|
|
410
|
-
if (!currentPage) {
|
|
411
|
-
return true
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
let config = currentPage.config ?? ({} as PageConfig)
|
|
415
|
-
if (__DEV__) {
|
|
416
|
-
if (this.pageRouteToConfig?.has(currentPage.route)) {
|
|
417
|
-
config = this.pageRouteToConfig.get(currentPage.route)!
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
const onBeforeLeave = config.hooks?.onBeforeLeave
|
|
422
|
-
if (onBeforeLeave) {
|
|
423
|
-
return runBeforeLeaveHooks(
|
|
424
|
-
toArray(onBeforeLeave),
|
|
425
|
-
{ ...requestContext.current },
|
|
426
|
-
to,
|
|
427
|
-
this.state.pathname
|
|
428
|
-
)
|
|
429
|
-
}
|
|
430
|
-
return true
|
|
431
|
-
}
|
|
432
|
-
|
|
433
316
|
public getChildren() {
|
|
434
317
|
const page = this.currentPage.value
|
|
435
318
|
if (!page) return null
|
|
@@ -450,14 +333,12 @@ export class FileRouterController {
|
|
|
450
333
|
fileRouterInstance.current = null
|
|
451
334
|
}
|
|
452
335
|
|
|
453
|
-
private async loadRoute(
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
} = options ?? {}
|
|
460
|
-
|
|
336
|
+
private async loadRoute(
|
|
337
|
+
path: string = window.location.pathname,
|
|
338
|
+
props: Record<string, unknown> = {},
|
|
339
|
+
enableTransition = this.enableTransitions,
|
|
340
|
+
isStatic404 = false
|
|
341
|
+
): Promise<void> {
|
|
461
342
|
this.abortController?.abort()
|
|
462
343
|
const signal = (this.abortController = new AbortController()).signal
|
|
463
344
|
|
|
@@ -482,38 +363,10 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
|
|
|
482
363
|
|
|
483
364
|
const { route, pageEntry, params, routeSegments } = routeMatch
|
|
484
365
|
|
|
485
|
-
// Apply beforeEach guards before loading route
|
|
486
|
-
const guardEntries = matchModules(
|
|
487
|
-
this.guards as unknown as FormattedViteImportMap,
|
|
488
|
-
routeSegments
|
|
489
|
-
)
|
|
490
|
-
const guardModules = await Promise.all(
|
|
491
|
-
guardEntries.map(
|
|
492
|
-
(entry) => entry.load() as unknown as Promise<GuardModule>
|
|
493
|
-
)
|
|
494
|
-
)
|
|
495
|
-
|
|
496
|
-
const fromPath = this.state.pathname
|
|
497
|
-
const redirectPath = await runBeforeEachGuards(
|
|
498
|
-
guardModules,
|
|
499
|
-
{ ...requestContext.current },
|
|
500
|
-
path,
|
|
501
|
-
fromPath
|
|
502
|
-
)
|
|
503
|
-
|
|
504
|
-
// If redirect was requested, navigate to that path instead
|
|
505
|
-
if (redirectPath !== null) {
|
|
506
|
-
this.state.pathname = path
|
|
507
|
-
return this.navigate(redirectPath, {
|
|
508
|
-
replace: true,
|
|
509
|
-
transition: enableTransition,
|
|
510
|
-
})
|
|
511
|
-
}
|
|
512
|
-
|
|
513
366
|
fileRouterRoute.current = route
|
|
514
367
|
const pagePromise = pageEntry.load()
|
|
515
368
|
|
|
516
|
-
const layoutPromises =
|
|
369
|
+
const layoutPromises = matchLayouts(this.layouts, routeSegments).map(
|
|
517
370
|
(layoutEntry) => layoutEntry.load()
|
|
518
371
|
)
|
|
519
372
|
|
|
@@ -547,77 +400,64 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
|
|
|
547
400
|
}
|
|
548
401
|
}
|
|
549
402
|
|
|
550
|
-
const { loader
|
|
403
|
+
const { loader } = config
|
|
551
404
|
|
|
552
|
-
if (
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
return this.navigate(redirectPath, {
|
|
562
|
-
replace: true,
|
|
563
|
-
transition: enableTransition,
|
|
564
|
-
})
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
let props: Record<string, unknown> = {}
|
|
569
|
-
if (!!loader) {
|
|
570
|
-
props = {
|
|
571
|
-
data: null,
|
|
572
|
-
error: null,
|
|
573
|
-
loading: true,
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
if (loader?.static && !__DEV__) {
|
|
578
|
-
const staticProps = page.__KIRU_STATIC_PROPS__?.[path]
|
|
579
|
-
if (!staticProps) {
|
|
580
|
-
// 404
|
|
581
|
-
return this.loadRoute({
|
|
582
|
-
path,
|
|
583
|
-
transition: enableTransition,
|
|
584
|
-
isStatic404: true,
|
|
585
|
-
})
|
|
586
|
-
}
|
|
587
|
-
const { data, error } = staticProps
|
|
588
|
-
props = error
|
|
589
|
-
? {
|
|
590
|
-
data: null,
|
|
591
|
-
error: new FileRouterDataLoadError(error),
|
|
592
|
-
loading: false,
|
|
405
|
+
if (loader) {
|
|
406
|
+
if (loader.mode !== "static" || __DEV__) {
|
|
407
|
+
// Check cache first if caching is enabled
|
|
408
|
+
let cachedData = null
|
|
409
|
+
if (loader.mode !== "static" && loader.cache) {
|
|
410
|
+
const cacheKey: CacheKey = {
|
|
411
|
+
path: routerState.pathname,
|
|
412
|
+
params: routerState.params,
|
|
413
|
+
query: routerState.query,
|
|
593
414
|
}
|
|
594
|
-
|
|
595
|
-
|
|
415
|
+
cachedData = routerCache.current!.get(cacheKey, loader.cache)
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if (cachedData !== null) {
|
|
419
|
+
// Use cached data immediately - no loading state needed
|
|
420
|
+
props = {
|
|
421
|
+
...props,
|
|
422
|
+
data: cachedData.value,
|
|
596
423
|
error: null,
|
|
597
424
|
loading: false,
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
425
|
+
} satisfies PageProps<PageConfig<unknown>>
|
|
426
|
+
} else {
|
|
427
|
+
// No cached data - show loading state and load data
|
|
428
|
+
props = {
|
|
429
|
+
...props,
|
|
430
|
+
loading: true,
|
|
431
|
+
data: null,
|
|
432
|
+
error: null,
|
|
433
|
+
} satisfies PageProps<PageConfig<unknown>>
|
|
606
434
|
|
|
607
|
-
|
|
435
|
+
this.loadRouteData(
|
|
436
|
+
config as PageConfigWithLoader,
|
|
437
|
+
props,
|
|
438
|
+
routerState,
|
|
439
|
+
enableTransition
|
|
440
|
+
)
|
|
441
|
+
}
|
|
442
|
+
} else {
|
|
443
|
+
const staticProps = page.__KIRU_STATIC_PROPS__?.[path]
|
|
444
|
+
if (!staticProps) {
|
|
445
|
+
return this.loadRoute(path, props, enableTransition, true)
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
const { data, error } = staticProps
|
|
608
449
|
props = {
|
|
609
|
-
|
|
610
|
-
|
|
450
|
+
...props,
|
|
451
|
+
data: data,
|
|
452
|
+
error: error ? new FileRouterDataLoadError(error) : null,
|
|
611
453
|
loading: false,
|
|
612
|
-
}
|
|
454
|
+
} as PageProps<PageConfig<unknown>>
|
|
613
455
|
}
|
|
614
456
|
}
|
|
615
457
|
|
|
616
|
-
|
|
617
|
-
let tId = transitionId++
|
|
618
|
-
|
|
619
|
-
return await handleStateTransition(enableTransition, tId, () => {
|
|
458
|
+
return handleStateTransition(signal, enableTransition, () => {
|
|
620
459
|
this.state = routerState
|
|
460
|
+
this.contextValue = this.createContextValue()
|
|
621
461
|
this.currentPage.value = {
|
|
622
462
|
component: page.default,
|
|
623
463
|
config,
|
|
@@ -627,25 +467,6 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
|
|
|
627
467
|
this.currentLayouts.value = layouts
|
|
628
468
|
.filter((m) => typeof m.default === "function")
|
|
629
469
|
.map((m) => m.default)
|
|
630
|
-
|
|
631
|
-
nextIdle(() => {
|
|
632
|
-
runAfterEachGuards(
|
|
633
|
-
guardModules,
|
|
634
|
-
{ ...requestContext.current },
|
|
635
|
-
path,
|
|
636
|
-
fromPath
|
|
637
|
-
)
|
|
638
|
-
if (props.loading) {
|
|
639
|
-
this.loadRouteData(
|
|
640
|
-
config as PageConfigWithLoader,
|
|
641
|
-
routerState,
|
|
642
|
-
enableTransition,
|
|
643
|
-
tId
|
|
644
|
-
).then(() => signal.aborted || onPaint?.())
|
|
645
|
-
} else {
|
|
646
|
-
onPaint?.()
|
|
647
|
-
}
|
|
648
|
-
})
|
|
649
470
|
})
|
|
650
471
|
} catch (error) {
|
|
651
472
|
console.error("[kiru/router]: Failed to load route component:", error)
|
|
@@ -655,19 +476,19 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
|
|
|
655
476
|
|
|
656
477
|
private async loadRouteData(
|
|
657
478
|
config: PageConfigWithLoader,
|
|
479
|
+
props: Record<string, unknown>,
|
|
658
480
|
routerState: RouterState,
|
|
659
|
-
enableTransition = this.enableTransitions
|
|
660
|
-
id = transitionId
|
|
481
|
+
enableTransition = this.enableTransitions
|
|
661
482
|
) {
|
|
662
483
|
const { loader } = config
|
|
663
484
|
|
|
664
485
|
// Load data from loader (cache check is now done earlier in loadRoute)
|
|
665
|
-
|
|
666
|
-
.load(
|
|
486
|
+
loader
|
|
487
|
+
.load(routerState)
|
|
667
488
|
.then(
|
|
668
489
|
(data) => {
|
|
669
490
|
// Cache the data if caching is enabled
|
|
670
|
-
if (
|
|
491
|
+
if (loader.mode !== "static" && loader.cache) {
|
|
671
492
|
const cacheKey: CacheKey = {
|
|
672
493
|
path: routerState.pathname,
|
|
673
494
|
params: routerState.params,
|
|
@@ -687,19 +508,20 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
|
|
|
687
508
|
data: null,
|
|
688
509
|
error: new FileRouterDataLoadError(error),
|
|
689
510
|
loading: false,
|
|
690
|
-
} satisfies PageProps<PageConfig<unknown>>
|
|
511
|
+
}) satisfies PageProps<PageConfig<unknown>>
|
|
691
512
|
)
|
|
692
513
|
.then((state) => {
|
|
693
514
|
if (routerState.signal.aborted) return
|
|
694
515
|
|
|
695
516
|
const transition =
|
|
696
|
-
(
|
|
517
|
+
(loader.mode !== "static" && loader.transition) ?? enableTransition
|
|
697
518
|
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
519
|
+
handleStateTransition(routerState.signal, transition, () => {
|
|
520
|
+
this.currentPageProps.value = {
|
|
521
|
+
...props,
|
|
522
|
+
...state,
|
|
523
|
+
} satisfies PageProps<PageConfig<unknown>>
|
|
524
|
+
})
|
|
703
525
|
})
|
|
704
526
|
}
|
|
705
527
|
|
|
@@ -727,17 +549,17 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
|
|
|
727
549
|
const url = new URL(path, "http://localhost")
|
|
728
550
|
const { hash: nextHash, pathname: nextPath } = url
|
|
729
551
|
const { hash: prevHash, pathname: prevPath } = this.state
|
|
730
|
-
if (
|
|
731
|
-
(nextHash === prevHash && nextPath === prevPath) ||
|
|
732
|
-
this.onBeforeLeave(prevPath) === false
|
|
733
|
-
) {
|
|
552
|
+
if (nextHash === prevHash && nextPath === prevPath) {
|
|
734
553
|
return
|
|
735
554
|
}
|
|
736
555
|
|
|
737
556
|
this.updateHistoryState(path, options)
|
|
738
557
|
|
|
739
|
-
|
|
740
|
-
|
|
558
|
+
this.loadRoute(
|
|
559
|
+
void 0,
|
|
560
|
+
void 0,
|
|
561
|
+
options?.transition ?? this.enableTransitions
|
|
562
|
+
).then(() => {
|
|
741
563
|
if (nextHash !== prevHash) {
|
|
742
564
|
window.dispatchEvent(new HashChangeEvent("hashchange"))
|
|
743
565
|
}
|
|
@@ -764,7 +586,7 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
|
|
|
764
586
|
const { pageEntry, route } = routeMatch
|
|
765
587
|
fileRouterRoute.current = route
|
|
766
588
|
const pagePromise = pageEntry.load()
|
|
767
|
-
const layoutPromises =
|
|
589
|
+
const layoutPromises = matchLayouts(this.layouts, route.split("/")).map(
|
|
768
590
|
(layoutEntry) => layoutEntry.load()
|
|
769
591
|
)
|
|
770
592
|
await Promise.all([pagePromise, ...layoutPromises])
|
|
@@ -810,15 +632,13 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
|
|
|
810
632
|
path
|
|
811
633
|
)
|
|
812
634
|
} else {
|
|
813
|
-
const current = scrollStack.get()
|
|
814
|
-
|
|
815
635
|
// if we've gone back and are now going forward, we need to
|
|
816
636
|
// truncate the scroll stack so it doesn't just permanently grow.
|
|
817
637
|
// this should keep it at the same length as the history stack.
|
|
638
|
+
const current = scrollStack.get()
|
|
818
639
|
if (this.historyIndex < window.history.length - 1) {
|
|
819
640
|
current.length = this.historyIndex
|
|
820
641
|
}
|
|
821
|
-
|
|
822
642
|
scrollStack.save([...current, [window.scrollX, window.scrollY]])
|
|
823
643
|
window.history.pushState(
|
|
824
644
|
{ ...window.history.state, index: ++this.historyIndex },
|
|
@@ -827,6 +647,32 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
|
|
|
827
647
|
)
|
|
828
648
|
}
|
|
829
649
|
}
|
|
650
|
+
private createContextValue() {
|
|
651
|
+
const __this = this
|
|
652
|
+
return {
|
|
653
|
+
get baseUrl() {
|
|
654
|
+
return __this.baseUrl
|
|
655
|
+
},
|
|
656
|
+
invalidate: async (...paths: string[]) => {
|
|
657
|
+
if (this.invalidate(...paths)) {
|
|
658
|
+
return this.loadRoute(void 0, void 0, true)
|
|
659
|
+
}
|
|
660
|
+
},
|
|
661
|
+
get state() {
|
|
662
|
+
return { ...__this.state }
|
|
663
|
+
},
|
|
664
|
+
navigate: this.navigate.bind(this),
|
|
665
|
+
prefetchRouteModules: this.prefetchRouteModules.bind(this),
|
|
666
|
+
reload: async (options?: ReloadOptions) => {
|
|
667
|
+
if (options?.invalidate ?? true) {
|
|
668
|
+
this.invalidate(this.state.pathname)
|
|
669
|
+
}
|
|
670
|
+
return this.loadRoute(void 0, void 0, options?.transition)
|
|
671
|
+
},
|
|
672
|
+
setQuery: this.setQuery.bind(this),
|
|
673
|
+
setHash: this.setHash.bind(this),
|
|
674
|
+
}
|
|
675
|
+
}
|
|
830
676
|
}
|
|
831
677
|
|
|
832
678
|
function buildQueryString(
|
|
@@ -848,32 +694,23 @@ function buildQueryString(
|
|
|
848
694
|
}
|
|
849
695
|
|
|
850
696
|
async function handleStateTransition(
|
|
697
|
+
signal: AbortSignal,
|
|
851
698
|
enableTransition: boolean,
|
|
852
|
-
id: number,
|
|
853
699
|
callback: () => void
|
|
854
700
|
) {
|
|
855
|
-
if (currentTransition) {
|
|
856
|
-
const { id: currentId, transition } = currentTransition
|
|
857
|
-
// for cross-page navigations, we skip any existing transitions.
|
|
858
|
-
// otherwise (eg. loaders), we wait for the existing transition to finish
|
|
859
|
-
if (id !== currentId) {
|
|
860
|
-
transition.skipTransition()
|
|
861
|
-
}
|
|
862
|
-
await transition.finished
|
|
863
|
-
}
|
|
864
701
|
if (!enableTransition || typeof document.startViewTransition !== "function") {
|
|
865
702
|
return new Promise<void>((resolve) => {
|
|
866
703
|
callback()
|
|
867
704
|
nextIdle(resolve)
|
|
868
705
|
})
|
|
869
706
|
}
|
|
870
|
-
const
|
|
707
|
+
const vt = document.startViewTransition(() => {
|
|
871
708
|
callback()
|
|
872
709
|
flushSync()
|
|
873
710
|
})
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
711
|
+
|
|
712
|
+
signal.addEventListener("abort", () => vt.skipTransition())
|
|
713
|
+
await vt.ready
|
|
877
714
|
}
|
|
878
715
|
|
|
879
716
|
function validateRoutes(pageMap: FormattedViteImportMap) {
|