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.
Files changed (204) hide show
  1. package/dist/components/derive.d.ts +1 -1
  2. package/dist/components/derive.d.ts.map +1 -1
  3. package/dist/components/derive.js +2 -3
  4. package/dist/components/derive.js.map +1 -1
  5. package/dist/components/memo.d.ts +1 -3
  6. package/dist/components/memo.d.ts.map +1 -1
  7. package/dist/components/memo.js +2 -2
  8. package/dist/components/memo.js.map +1 -1
  9. package/dist/context.d.ts.map +1 -1
  10. package/dist/context.js +1 -23
  11. package/dist/context.js.map +1 -1
  12. package/dist/dom.d.ts.map +1 -1
  13. package/dist/dom.js +111 -78
  14. package/dist/dom.js.map +1 -1
  15. package/dist/error.d.ts.map +1 -1
  16. package/dist/error.js +2 -4
  17. package/dist/error.js.map +1 -1
  18. package/dist/form/index.d.ts.map +1 -1
  19. package/dist/form/index.js +6 -10
  20. package/dist/form/index.js.map +1 -1
  21. package/dist/globals.d.ts +1 -1
  22. package/dist/globals.d.ts.map +1 -1
  23. package/dist/globals.js.map +1 -1
  24. package/dist/hmr.d.ts +1 -0
  25. package/dist/hmr.d.ts.map +1 -1
  26. package/dist/hmr.js +11 -3
  27. package/dist/hmr.js.map +1 -1
  28. package/dist/hooks/useEffectEvent.d.ts.map +1 -1
  29. package/dist/hooks/useEffectEvent.js.map +1 -1
  30. package/dist/hooks/usePromise.d.ts +1 -2
  31. package/dist/hooks/usePromise.d.ts.map +1 -1
  32. package/dist/hooks/usePromise.js +62 -31
  33. package/dist/hooks/usePromise.js.map +1 -1
  34. package/dist/hooks/utils.d.ts.map +1 -1
  35. package/dist/hooks/utils.js +10 -10
  36. package/dist/hooks/utils.js.map +1 -1
  37. package/dist/hydration.d.ts +6 -13
  38. package/dist/hydration.d.ts.map +1 -1
  39. package/dist/hydration.js +20 -50
  40. package/dist/hydration.js.map +1 -1
  41. package/dist/index.js +2 -1
  42. package/dist/index.js.map +1 -1
  43. package/dist/reconciler.d.ts.map +1 -1
  44. package/dist/reconciler.js +3 -6
  45. package/dist/reconciler.js.map +1 -1
  46. package/dist/recursiveRender.d.ts.map +1 -1
  47. package/dist/recursiveRender.js +9 -8
  48. package/dist/recursiveRender.js.map +1 -1
  49. package/dist/renderToString.d.ts.map +1 -1
  50. package/dist/renderToString.js.map +1 -1
  51. package/dist/router/client/index.d.ts +2 -4
  52. package/dist/router/client/index.d.ts.map +1 -1
  53. package/dist/router/client/index.js +13 -59
  54. package/dist/router/client/index.js.map +1 -1
  55. package/dist/router/context.d.ts +5 -2
  56. package/dist/router/context.d.ts.map +1 -1
  57. package/dist/router/context.js +1 -5
  58. package/dist/router/context.js.map +1 -1
  59. package/dist/router/fileRouter.d.ts.map +1 -1
  60. package/dist/router/fileRouter.js +2 -4
  61. package/dist/router/fileRouter.js.map +1 -1
  62. package/dist/router/fileRouterController.d.ts +2 -2
  63. package/dist/router/fileRouterController.d.ts.map +1 -1
  64. package/dist/router/fileRouterController.js +135 -214
  65. package/dist/router/fileRouterController.js.map +1 -1
  66. package/dist/router/globals.d.ts +0 -3
  67. package/dist/router/globals.d.ts.map +1 -1
  68. package/dist/router/globals.js +0 -3
  69. package/dist/router/globals.js.map +1 -1
  70. package/dist/router/head.d.ts.map +1 -1
  71. package/dist/router/head.js +7 -5
  72. package/dist/router/head.js.map +1 -1
  73. package/dist/router/index.d.ts +1 -2
  74. package/dist/router/index.d.ts.map +1 -1
  75. package/dist/router/index.js +1 -2
  76. package/dist/router/index.js.map +1 -1
  77. package/dist/router/link.js +3 -3
  78. package/dist/router/link.js.map +1 -1
  79. package/dist/router/{ssg → server}/index.d.ts +4 -4
  80. package/dist/router/server/index.d.ts.map +1 -0
  81. package/dist/router/{ssg → server}/index.js +7 -9
  82. package/dist/router/server/index.js.map +1 -0
  83. package/dist/router/types.d.ts +16 -42
  84. package/dist/router/types.d.ts.map +1 -1
  85. package/dist/router/types.internal.d.ts +0 -4
  86. package/dist/router/types.internal.d.ts.map +1 -1
  87. package/dist/router/utils/index.d.ts +3 -8
  88. package/dist/router/utils/index.d.ts.map +1 -1
  89. package/dist/router/utils/index.js +8 -40
  90. package/dist/router/utils/index.js.map +1 -1
  91. package/dist/scheduler.d.ts +3 -14
  92. package/dist/scheduler.d.ts.map +1 -1
  93. package/dist/scheduler.js +64 -56
  94. package/dist/scheduler.js.map +1 -1
  95. package/dist/signals/base.d.ts +0 -2
  96. package/dist/signals/base.d.ts.map +1 -1
  97. package/dist/signals/base.js +0 -6
  98. package/dist/signals/base.js.map +1 -1
  99. package/dist/signals/computed.d.ts +3 -0
  100. package/dist/signals/computed.d.ts.map +1 -1
  101. package/dist/signals/computed.js +29 -20
  102. package/dist/signals/computed.js.map +1 -1
  103. package/dist/signals/for.d.ts +3 -3
  104. package/dist/signals/for.d.ts.map +1 -1
  105. package/dist/signals/for.js +2 -1
  106. package/dist/signals/for.js.map +1 -1
  107. package/dist/signals/utils.d.ts.map +1 -1
  108. package/dist/signals/utils.js +2 -1
  109. package/dist/signals/utils.js.map +1 -1
  110. package/dist/signals/watch.d.ts.map +1 -1
  111. package/dist/signals/watch.js +18 -22
  112. package/dist/signals/watch.js.map +1 -1
  113. package/dist/ssr/client.d.ts +1 -1
  114. package/dist/ssr/client.d.ts.map +1 -1
  115. package/dist/ssr/client.js +0 -2
  116. package/dist/ssr/client.js.map +1 -1
  117. package/dist/ssr/server.d.ts +3 -9
  118. package/dist/ssr/server.d.ts.map +1 -1
  119. package/dist/ssr/server.js +30 -37
  120. package/dist/ssr/server.js.map +1 -1
  121. package/dist/types.d.ts +0 -7
  122. package/dist/types.d.ts.map +1 -1
  123. package/dist/types.dom.d.ts +3 -3
  124. package/dist/types.dom.d.ts.map +1 -1
  125. package/dist/utils/format.d.ts +1 -2
  126. package/dist/utils/format.d.ts.map +1 -1
  127. package/dist/utils/format.js +1 -4
  128. package/dist/utils/format.js.map +1 -1
  129. package/dist/utils/index.d.ts +1 -1
  130. package/dist/utils/index.d.ts.map +1 -1
  131. package/dist/utils/index.js +1 -1
  132. package/dist/utils/index.js.map +1 -1
  133. package/dist/utils/promise.d.ts +0 -2
  134. package/dist/utils/promise.d.ts.map +1 -1
  135. package/dist/utils/promise.js +1 -45
  136. package/dist/utils/promise.js.map +1 -1
  137. package/dist/utils/runtime.d.ts +3 -2
  138. package/dist/utils/runtime.d.ts.map +1 -1
  139. package/dist/utils/runtime.js +5 -2
  140. package/dist/utils/runtime.js.map +1 -1
  141. package/dist/utils/vdom.d.ts.map +1 -1
  142. package/dist/utils/vdom.js +2 -2
  143. package/dist/utils/vdom.js.map +1 -1
  144. package/package.json +4 -8
  145. package/src/components/derive.ts +3 -5
  146. package/src/components/memo.ts +3 -11
  147. package/src/context.ts +1 -24
  148. package/src/dom.ts +146 -101
  149. package/src/error.ts +2 -4
  150. package/src/form/index.ts +6 -9
  151. package/src/globals.ts +1 -1
  152. package/src/hmr.ts +14 -5
  153. package/src/hooks/useEffectEvent.ts +0 -1
  154. package/src/hooks/usePromise.ts +77 -58
  155. package/src/hooks/utils.ts +12 -12
  156. package/src/hydration.ts +21 -57
  157. package/src/index.ts +1 -1
  158. package/src/reconciler.ts +2 -6
  159. package/src/recursiveRender.ts +10 -9
  160. package/src/renderToString.ts +0 -1
  161. package/src/router/client/index.ts +16 -114
  162. package/src/router/context.ts +6 -7
  163. package/src/router/fileRouter.ts +2 -6
  164. package/src/router/fileRouterController.ts +161 -324
  165. package/src/router/globals.ts +0 -4
  166. package/src/router/head.ts +7 -5
  167. package/src/router/index.ts +1 -12
  168. package/src/router/link.ts +3 -3
  169. package/src/router/{ssg → server}/index.ts +13 -18
  170. package/src/router/types.internal.ts +0 -5
  171. package/src/router/types.ts +16 -53
  172. package/src/router/utils/index.ts +16 -79
  173. package/src/scheduler.ts +85 -89
  174. package/src/signals/base.ts +0 -8
  175. package/src/signals/computed.ts +30 -18
  176. package/src/signals/for.ts +15 -10
  177. package/src/signals/utils.ts +2 -1
  178. package/src/signals/watch.ts +27 -22
  179. package/src/ssr/client.ts +1 -4
  180. package/src/ssr/server.ts +34 -59
  181. package/src/types.dom.ts +4 -5
  182. package/src/types.ts +0 -10
  183. package/src/utils/format.ts +0 -5
  184. package/src/utils/index.ts +1 -1
  185. package/src/utils/promise.ts +1 -70
  186. package/src/utils/runtime.ts +6 -2
  187. package/src/utils/vdom.ts +2 -7
  188. package/dist/router/constants.d.ts +0 -2
  189. package/dist/router/constants.d.ts.map +0 -1
  190. package/dist/router/constants.js +0 -2
  191. package/dist/router/constants.js.map +0 -1
  192. package/dist/router/guard.d.ts +0 -17
  193. package/dist/router/guard.d.ts.map +0 -1
  194. package/dist/router/guard.js +0 -45
  195. package/dist/router/guard.js.map +0 -1
  196. package/dist/router/ssg/index.d.ts.map +0 -1
  197. package/dist/router/ssg/index.js.map +0 -1
  198. package/dist/router/ssr/index.d.ts +0 -20
  199. package/dist/router/ssr/index.d.ts.map +0 -1
  200. package/dist/router/ssr/index.js +0 -163
  201. package/dist/router/ssr/index.js.map +0 -1
  202. package/src/router/constants.ts +0 -1
  203. package/src/router/guard.ts +0 -72
  204. package/src/router/ssr/index.ts +0 -252
@@ -3,6 +3,7 @@ import { __DEV__ } from "../env.js"
3
3
  import { hookIndex, node } from "../globals.js"
4
4
  import { noop } from "../utils/index.js"
5
5
  import { requestUpdate } from "../scheduler.js"
6
+ import { isHmrUpdate } from "../hmr.js"
6
7
  export {
7
8
  cleanupHook,
8
9
  depsRequireChange,
@@ -115,17 +116,16 @@ function useHook<
115
116
  ): ReturnType<U> {
116
117
  const vNode = getVNodeOrError(hookName)
117
118
 
118
- if (__DEV__) {
119
- if (
120
- currentHookName !== null &&
121
- !nestedHookWarnings.has(hookName + currentHookName)
122
- ) {
123
- nestedHookWarnings.add(hookName + currentHookName)
124
- throw new KiruError({
125
- message: `Nested primitive "useHook" calls are not supported. "${hookName}" was called inside "${currentHookName}". Strange will most certainly happen.`,
126
- vNode,
127
- })
128
- }
119
+ if (
120
+ __DEV__ &&
121
+ currentHookName !== null &&
122
+ !nestedHookWarnings.has(hookName + currentHookName)
123
+ ) {
124
+ nestedHookWarnings.add(hookName + currentHookName)
125
+ throw new KiruError({
126
+ message: `Nested primitive "useHook" calls are not supported. "${hookName}" was called inside "${currentHookName}". Strange will most certainly happen.`,
127
+ vNode,
128
+ })
129
129
  }
130
130
 
131
131
  const queueEffect = (callback: Function, opts?: { immediate?: boolean }) => {
@@ -177,7 +177,7 @@ function useHook<
177
177
  const res = (callback as HookCallback<T>)({
178
178
  hook,
179
179
  isInit: !oldHook,
180
- isHMR: vNode.hmrUpdated,
180
+ isHMR: isHmrUpdate(),
181
181
  update: () => requestUpdate(vNode),
182
182
  queueEffect,
183
183
  vNode,
package/src/hydration.ts CHANGED
@@ -1,67 +1,31 @@
1
1
  import type { MaybeDom, SomeDom } from "./types.utils"
2
2
 
3
+ const parents: SomeDom[] = []
4
+ const childIdx: number[] = []
5
+
3
6
  export const hydrationStack = {
4
- parentStack: [] as Array<SomeDom>,
5
- childIdxStack: [] as Array<number>,
6
- eventDeferrals: new Map<Element, Array<() => void>>(),
7
- parent: function () {
8
- return this.parentStack[this.parentStack.length - 1]
9
- },
10
- clear: function () {
11
- this.parentStack.length = 0
12
- this.childIdxStack.length = 0
13
- },
14
- pop: function () {
15
- this.parentStack.pop()
16
- this.childIdxStack.pop()
17
- },
18
- push: function (el: SomeDom) {
19
- this.parentStack.push(el)
20
- this.childIdxStack.push(0)
7
+ bumpChildIndex() {
8
+ childIdx[childIdx.length - 1]++
21
9
  },
22
- currentChild: function () {
23
- return this.parentStack[this.parentStack.length - 1].childNodes[
24
- this.childIdxStack[this.childIdxStack.length - 1]
25
- ]
10
+ getCurrentChild(): MaybeDom {
11
+ const idx = childIdx[childIdx.length - 1]
12
+ // @ts-expect-error TODO: We're ignoring the possibility of encountering comment or cdata nodes.
13
+ // Not really a problem for now since we don't render those but should be checked anyway.
14
+ return this.getCurrentParent().childNodes[idx]
26
15
  },
27
- nextChild: function () {
28
- return this.parentStack[this.parentStack.length - 1].childNodes[
29
- this.childIdxStack[this.childIdxStack.length - 1]++
30
- ] as MaybeDom
16
+ getCurrentParent() {
17
+ return parents[parents.length - 1]
31
18
  },
32
- bumpChildIndex: function () {
33
- this.childIdxStack[this.childIdxStack.length - 1]++
19
+ clear() {
20
+ parents.length = 0
21
+ childIdx.length = 0
34
22
  },
35
- captureEvents: function (element: Element) {
36
- toggleEvtListeners(element, true)
37
- this.eventDeferrals.set(element, [])
23
+ pop() {
24
+ parents.pop()
25
+ childIdx.pop()
38
26
  },
39
- resetEvents: function (element: Element) {
40
- this.eventDeferrals.delete(element)
27
+ push(el: SomeDom) {
28
+ parents.push(el)
29
+ childIdx.push(0)
41
30
  },
42
- releaseEvents: function (element: Element) {
43
- toggleEvtListeners(element, false)
44
- const events = this.eventDeferrals.get(element)
45
- while (events?.length) events.shift()!()
46
- },
47
- }
48
-
49
- const captureEvent = (e: Event) => {
50
- const t = e.target
51
- if (!e.isTrusted || !t) return
52
- hydrationStack.eventDeferrals
53
- .get(t as Element)
54
- ?.push(() => t.dispatchEvent(e))
55
- }
56
- const toggleEvtListeners = (element: Element, value: boolean) => {
57
- for (const key in element) {
58
- if (key.startsWith("on")) {
59
- const eventType = key.substring(2)
60
- element[value ? "addEventListener" : "removeEventListener"](
61
- eventType,
62
- captureEvent,
63
- { passive: true }
64
- )
65
- }
66
- }
67
31
  }
package/src/index.ts CHANGED
@@ -16,5 +16,5 @@ export * from "./store.js"
16
16
 
17
17
  // @ts-ignore
18
18
  if ("window" in globalThis && !globalThis.__KIRU_DEVTOOLS__) {
19
- window.__kiru ??= createKiruGlobalContext()
19
+ globalThis.window.__kiru ??= createKiruGlobalContext()
20
20
  }
package/src/reconciler.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  $FRAGMENT,
3
- $MEMO,
4
3
  FLAG_MEMO,
5
4
  FLAG_PLACEMENT,
6
5
  FLAG_UPDATE,
@@ -221,10 +220,8 @@ function updateTextNode(
221
220
 
222
221
  function updateNode(parent: VNode, oldChild: VNode | null, newChild: KElement) {
223
222
  let { type, props, key } = newChild
224
- if (__DEV__) {
225
- if (typeof type === "function") {
226
- type = latest(type)
227
- }
223
+ if (__DEV__ && typeof type === "function") {
224
+ type = latest(type)
228
225
  }
229
226
  if (type === $FRAGMENT) {
230
227
  return updateFragment(
@@ -499,7 +496,6 @@ function createVNode(
499
496
 
500
497
  if (typeof type === "function" && isMemoFn(type)) {
501
498
  node.flags |= FLAG_MEMO
502
- node.arePropsEqual = type[$MEMO].arePropsEqual
503
499
  }
504
500
 
505
501
  if (__DEV__ && "window" in globalThis) {
@@ -6,6 +6,7 @@ import {
6
6
  isExoticType,
7
7
  assertValidElementProps,
8
8
  isPrimitiveChild,
9
+ isValidTextChild,
9
10
  } from "./utils/index.js"
10
11
  import { isStreamDataThrowValue } from "./utils/promise.js"
11
12
  import { Signal } from "./signals/base.js"
@@ -40,17 +41,17 @@ function render(
40
41
  }
41
42
  if (Signal.isSignal(el)) {
42
43
  const value = el.peek()
43
- if (__DEV__) {
44
- if (!isPrimitiveChild(value)) {
45
- if (__DEV__) {
46
- console.error(
47
- `[kiru]: expected primitive child but received ${value}`
48
- )
49
- }
50
- return
44
+ if (!isPrimitiveChild(value)) {
45
+ if (__DEV__) {
46
+ console.error(`[kiru]: expected primitive child but received ${value}`)
51
47
  }
48
+ return
52
49
  }
53
- return ctx.write(encodeHtmlEntities(String(value)))
50
+
51
+ if (isValidTextChild(value)) {
52
+ ctx.write(encodeHtmlEntities(String(value)))
53
+ }
54
+ return
54
55
  }
55
56
  if (!isVNode(el)) {
56
57
  return
@@ -1,6 +1,5 @@
1
1
  import { renderMode } from "./globals.js"
2
2
  import { Fragment } from "./element.js"
3
- import { __DEV__ } from "./env.js"
4
3
  import { headlessRender, HeadlessRenderContext } from "./recursiveRender.js"
5
4
 
6
5
  export function renderToString(element: JSX.Element) {
@@ -1,91 +1,45 @@
1
+ // initClient({ dir, baseUrl, pages, layouts })
2
+
1
3
  import { createElement } from "../../element.js"
2
4
  import { hydrate } from "../../ssr/client.js"
3
5
  import { FileRouter } from "../fileRouter.js"
4
- import { toArray } from "../../utils/format.js"
5
- import { resolveStreamedPromise } from "../../utils/promise.js"
6
6
  import {
7
- matchModules,
7
+ matchLayouts,
8
8
  matchRoute,
9
9
  match404Route,
10
10
  parseQuery,
11
- runBeforeEachGuards,
12
- runAfterEachGuards,
13
- runBeforeEnterHooks,
14
11
  } from "../utils/index.js"
15
- import type {
16
- FormattedViteImportMap,
17
- GuardModule,
18
- PageModule,
19
- } from "../types.internal"
12
+ import type { FormattedViteImportMap, PageModule } from "../types.internal"
20
13
  import type { FileRouterConfig, FileRouterPreloadConfig } from "../types"
21
- import {
22
- fileRouterInstance,
23
- fileRouterRoute,
24
- requestContext,
25
- routerCache,
26
- } from "../globals.js"
14
+ import { fileRouterInstance, fileRouterRoute, routerCache } from "../globals.js"
27
15
  import { FileRouterController } from "../fileRouterController.js"
28
16
  import { FileRouterDataLoadError } from "../errors.js"
29
17
  import { __DEV__ } from "../../env.js"
30
18
  import { RouterCache } from "../cache.js"
31
- import { RequestContext } from "../context.js"
32
- import { PAGE_DATA_PROMISE_ID } from "../constants.js"
33
- import { AsyncTaskState } from "../../types.js"
34
19
 
35
20
  interface InitClientOptions {
36
21
  dir: string
37
22
  baseUrl: string
38
- pages: FormattedViteImportMap<PageModule>
23
+ pages: FormattedViteImportMap
39
24
  layouts: FormattedViteImportMap
40
- guards?: FormattedViteImportMap<GuardModule>
41
25
  transition: boolean
42
- hydrationMode?: Kiru.HydrationMode
43
26
  }
44
27
 
45
28
  export async function initClient(options: InitClientOptions) {
46
29
  routerCache.current = new RouterCache()
47
- const {
48
- dir,
49
- baseUrl,
50
- pages,
51
- layouts,
52
- guards,
53
- transition,
54
- hydrationMode = "static",
55
- } = options
30
+ const { dir, baseUrl, pages, layouts, transition } = options
56
31
 
57
- try {
58
- requestContext.current = JSON.parse(
59
- document.querySelector("[k-request-context]")!.innerHTML
60
- )
61
- } catch {}
62
-
63
- const preloaded = await preparePreloadConfig(
64
- options,
65
- false,
66
- hydrationMode === "dynamic"
67
- )
68
32
  const config: FileRouterConfig = {
69
33
  dir,
70
34
  baseUrl,
71
35
  pages,
72
36
  layouts,
73
- guards,
74
37
  transition,
75
- preloaded,
38
+ preloaded: await preparePreloadConfig(options),
76
39
  }
77
40
 
78
- const children = createElement(FileRouter, { config })
79
-
80
- const app =
81
- hydrationMode === "static"
82
- ? children
83
- : createElement(RequestContext.Provider, {
84
- value: requestContext.current,
85
- children,
86
- })
87
-
88
- hydrate(app, document.body, { hydrationMode })
41
+ const app = createElement(FileRouter, { config })
42
+ hydrate(app, document.body, { hydrationMode: "static" })
89
43
 
90
44
  if (__DEV__) {
91
45
  onLoadedDev()
@@ -94,8 +48,7 @@ export async function initClient(options: InitClientOptions) {
94
48
 
95
49
  async function preparePreloadConfig(
96
50
  options: InitClientOptions,
97
- isStatic404 = false,
98
- isSSR = false
51
+ isStatic404 = false
99
52
  ): Promise<FileRouterPreloadConfig> {
100
53
  let pageProps = {}
101
54
  let cacheData: null | { value: unknown } = null
@@ -115,25 +68,7 @@ async function preparePreloadConfig(
115
68
  throw new Error(`No route defined (path: ${url.pathname}).`)
116
69
  }
117
70
 
118
- const layoutEntries = matchModules(options.layouts, routeMatch.routeSegments)
119
-
120
- // Load and run guards before loading page
121
- // if SSR, do we even need to do this?
122
- let guardModules: GuardModule[] = []
123
- if (options.guards) {
124
- const guardEntries = matchModules(options.guards, routeMatch.routeSegments)
125
- guardModules = await Promise.all(guardEntries.map((entry) => entry.load()))
126
-
127
- const redirectPath = await runBeforeEachGuards(
128
- guardModules,
129
- { ...requestContext.current },
130
- url.pathname
131
- )
132
- if (redirectPath !== null) {
133
- window.location.href = redirectPath
134
- }
135
- }
136
-
71
+ const layoutEntries = matchLayouts(options.layouts, routeMatch.routeSegments)
137
72
  fileRouterInstance.current = new FileRouterController()
138
73
  fileRouterRoute.current = routeMatch.route
139
74
  const [page, ...layouts] = await Promise.all([
@@ -142,26 +77,6 @@ async function preparePreloadConfig(
142
77
  ])
143
78
  fileRouterRoute.current = null
144
79
 
145
- const onBeforeEnter = page.config?.hooks?.onBeforeEnter
146
- if (onBeforeEnter) {
147
- const redirectPath = await runBeforeEnterHooks(
148
- toArray(onBeforeEnter),
149
- { ...requestContext.current },
150
- url.pathname
151
- )
152
- if (redirectPath !== null) {
153
- window.location.href = redirectPath
154
- // @ts-ignore
155
- return
156
- }
157
- }
158
-
159
- const query = parseQuery(window.location.search)
160
-
161
- let pagePropsPromise:
162
- | Promise<AsyncTaskState<unknown, FileRouterDataLoadError>>
163
- | undefined
164
-
165
80
  // Check if page has static props pre-loaded at build time
166
81
  if (page.__KIRU_STATIC_PROPS__) {
167
82
  const staticProps = page.__KIRU_STATIC_PROPS__[window.location.pathname]
@@ -180,39 +95,26 @@ async function preparePreloadConfig(
180
95
  pageProps = { loading: true, data: null, error: null }
181
96
 
182
97
  const loader = page.config.loader
183
- if (isSSR) {
184
- pagePropsPromise = resolveStreamedPromise(PAGE_DATA_PROMISE_ID)
185
- .then((data) => ({ data, error: null, loading: false } as const))
186
- .catch((error) => ({ data: null, error, loading: false } as const))
187
- } else if (!loader.static && loader.cache) {
98
+ // Check cache first if caching is enabled
99
+ if (loader.mode !== "static" && loader.cache) {
188
100
  const cacheKey = {
189
101
  path: window.location.pathname,
190
102
  params: routeMatch.params,
191
- query,
103
+ query: parseQuery(url.search),
192
104
  }
193
105
 
194
106
  cacheData = routerCache.current!.get(cacheKey, loader.cache)
195
107
  }
196
108
  }
197
109
 
198
- window.__kiru.on("mount", () => {
199
- runAfterEachGuards(
200
- guardModules,
201
- { ...requestContext.current },
202
- url.pathname
203
- )
204
- })
205
-
206
110
  return {
207
111
  pages: options.pages,
208
112
  layouts: options.layouts,
209
- guards: options.guards,
210
113
  page: page,
211
114
  pageProps: pageProps,
212
- pagePropsPromise,
213
115
  pageLayouts: layouts,
214
116
  params: routeMatch.params,
215
- query: query,
117
+ query: parseQuery(url.search),
216
118
  route: routeMatch.route,
217
119
  cacheData,
218
120
  }
@@ -1,6 +1,6 @@
1
- import { useContext } from "../hooks/index.js"
2
1
  import { createContext } from "../context.js"
3
2
  import { __DEV__ } from "../env.js"
3
+ import { useContext } from "../hooks/index.js"
4
4
  import type { RouteQuery, RouterState } from "./types.js"
5
5
 
6
6
  export interface ReloadOptions {
@@ -17,6 +17,11 @@ export interface ReloadOptions {
17
17
  }
18
18
 
19
19
  export interface FileRouterContextType {
20
+ /**
21
+ * The base URL of the router
22
+ * @default "/"
23
+ */
24
+ baseUrl: string
20
25
  /**
21
26
  * Invalidate cached loader data for the given paths
22
27
  * @example
@@ -74,9 +79,3 @@ if (__DEV__) {
74
79
  export function useFileRouter(): FileRouterContextType {
75
80
  return useContext(RouterContext)
76
81
  }
77
-
78
- export const RequestContext = createContext<Kiru.RequestContext>({})
79
-
80
- export function useRequestContext() {
81
- return useContext(RequestContext)
82
- }
@@ -26,12 +26,8 @@ export interface FileRouterProps {
26
26
 
27
27
  export function FileRouter({ config }: FileRouterProps): JSX.Element {
28
28
  const [controller] = useState(() => {
29
- if (fileRouterInstance.current && !config.preloaded) {
30
- throw new Error(
31
- "[kiru/router]: FileRouter cannot be instantiated more than once at a time."
32
- )
33
- }
34
- const router = (fileRouterInstance.current ??= new FileRouterController())
29
+ fileRouterInstance.current?.dispose()
30
+ const router = (fileRouterInstance.current = new FileRouterController())
35
31
  router.init(config)
36
32
  return router
37
33
  })