kiru 0.54.3 → 1.0.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 (335) hide show
  1. package/dist/{appContext.d.ts → appHandle.d.ts} +4 -4
  2. package/dist/appHandle.d.ts.map +1 -0
  3. package/dist/{appContext.js → appHandle.js} +12 -9
  4. package/dist/appHandle.js.map +1 -0
  5. package/dist/components/derive.d.ts +10 -8
  6. package/dist/components/derive.d.ts.map +1 -1
  7. package/dist/components/derive.js +50 -47
  8. package/dist/components/derive.js.map +1 -1
  9. package/dist/components/index.d.ts +0 -1
  10. package/dist/components/index.d.ts.map +1 -1
  11. package/dist/components/index.js +0 -1
  12. package/dist/components/index.js.map +1 -1
  13. package/dist/components/lazy.d.ts.map +1 -1
  14. package/dist/components/lazy.js +5 -4
  15. package/dist/components/lazy.js.map +1 -1
  16. package/dist/components/portal.d.ts.map +1 -1
  17. package/dist/components/portal.js +2 -3
  18. package/dist/components/portal.js.map +1 -1
  19. package/dist/components/transition.d.ts +3 -2
  20. package/dist/components/transition.d.ts.map +1 -1
  21. package/dist/components/transition.js +29 -26
  22. package/dist/components/transition.js.map +1 -1
  23. package/dist/constants.d.ts +1 -5
  24. package/dist/constants.d.ts.map +1 -1
  25. package/dist/constants.js +1 -5
  26. package/dist/constants.js.map +1 -1
  27. package/dist/context.d.ts +1 -1
  28. package/dist/context.d.ts.map +1 -1
  29. package/dist/context.js +25 -19
  30. package/dist/context.js.map +1 -1
  31. package/dist/devtools.d.ts +7 -0
  32. package/dist/devtools.d.ts.map +1 -0
  33. package/dist/devtools.js +15 -0
  34. package/dist/devtools.js.map +1 -0
  35. package/dist/dom.d.ts.map +1 -1
  36. package/dist/dom.js +25 -58
  37. package/dist/dom.js.map +1 -1
  38. package/dist/globalContext.d.ts +15 -16
  39. package/dist/globalContext.d.ts.map +1 -1
  40. package/dist/globalContext.js +36 -46
  41. package/dist/globalContext.js.map +1 -1
  42. package/dist/globals.d.ts +1 -4
  43. package/dist/globals.d.ts.map +1 -1
  44. package/dist/globals.js +1 -4
  45. package/dist/globals.js.map +1 -1
  46. package/dist/headlessRender.d.ts +6 -0
  47. package/dist/headlessRender.d.ts.map +1 -0
  48. package/dist/{recursiveRender.js → headlessRender.js} +17 -16
  49. package/dist/headlessRender.js.map +1 -0
  50. package/dist/hmr.d.ts +5 -7
  51. package/dist/hmr.d.ts.map +1 -1
  52. package/dist/hmr.js +27 -32
  53. package/dist/hmr.js.map +1 -1
  54. package/dist/hooks/index.d.ts +3 -14
  55. package/dist/hooks/index.d.ts.map +1 -1
  56. package/dist/hooks/index.js +3 -14
  57. package/dist/hooks/index.js.map +1 -1
  58. package/dist/hooks/onBeforeMount.d.ts +9 -0
  59. package/dist/hooks/onBeforeMount.d.ts.map +1 -0
  60. package/dist/hooks/onBeforeMount.js +12 -0
  61. package/dist/hooks/onBeforeMount.js.map +1 -0
  62. package/dist/hooks/onCleanup.d.ts +8 -0
  63. package/dist/hooks/onCleanup.d.ts.map +1 -0
  64. package/dist/hooks/onCleanup.js +15 -0
  65. package/dist/hooks/onCleanup.js.map +1 -0
  66. package/dist/hooks/onMount.d.ts +9 -0
  67. package/dist/hooks/onMount.d.ts.map +1 -0
  68. package/dist/hooks/onMount.js +12 -0
  69. package/dist/hooks/onMount.js.map +1 -0
  70. package/dist/hooks/utils.d.ts +2 -62
  71. package/dist/hooks/utils.d.ts.map +1 -1
  72. package/dist/hooks/utils.js +22 -144
  73. package/dist/hooks/utils.js.map +1 -1
  74. package/dist/index.d.ts +8 -4
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +8 -6
  77. package/dist/index.js.map +1 -1
  78. package/dist/profiling.d.ts +15 -14
  79. package/dist/profiling.d.ts.map +1 -1
  80. package/dist/profiling.js +9 -4
  81. package/dist/profiling.js.map +1 -1
  82. package/dist/reconciler.d.ts.map +1 -1
  83. package/dist/reconciler.js +12 -25
  84. package/dist/reconciler.js.map +1 -1
  85. package/dist/ref.d.ts +4 -0
  86. package/dist/ref.d.ts.map +1 -0
  87. package/dist/ref.js +4 -0
  88. package/dist/ref.js.map +1 -0
  89. package/dist/renderToString.js +1 -1
  90. package/dist/renderToString.js.map +1 -1
  91. package/dist/router/context.d.ts.map +1 -1
  92. package/dist/router/context.js +1 -2
  93. package/dist/router/context.js.map +1 -1
  94. package/dist/router/fileRouter.d.ts +1 -1
  95. package/dist/router/fileRouter.d.ts.map +1 -1
  96. package/dist/router/fileRouter.js +17 -11
  97. package/dist/router/fileRouter.js.map +1 -1
  98. package/dist/router/fileRouterController.d.ts.map +1 -1
  99. package/dist/router/fileRouterController.js +68 -55
  100. package/dist/router/fileRouterController.js.map +1 -1
  101. package/dist/router/link.d.ts.map +1 -1
  102. package/dist/router/link.js +19 -23
  103. package/dist/router/link.js.map +1 -1
  104. package/dist/router/server/index.d.ts.map +1 -1
  105. package/dist/router/server/index.js +14 -11
  106. package/dist/router/server/index.js.map +1 -1
  107. package/dist/router/types.d.ts +11 -6
  108. package/dist/router/types.d.ts.map +1 -1
  109. package/dist/scheduler.d.ts +1 -0
  110. package/dist/scheduler.d.ts.map +1 -1
  111. package/dist/scheduler.js +65 -52
  112. package/dist/scheduler.js.map +1 -1
  113. package/dist/signals/base.d.ts +0 -1
  114. package/dist/signals/base.d.ts.map +1 -1
  115. package/dist/signals/base.js +13 -36
  116. package/dist/signals/base.js.map +1 -1
  117. package/dist/signals/computed.d.ts +0 -2
  118. package/dist/signals/computed.d.ts.map +1 -1
  119. package/dist/signals/computed.js +1 -40
  120. package/dist/signals/computed.js.map +1 -1
  121. package/dist/signals/effect.d.ts +15 -14
  122. package/dist/signals/effect.d.ts.map +1 -1
  123. package/dist/signals/effect.js +65 -37
  124. package/dist/signals/effect.js.map +1 -1
  125. package/dist/signals/globals.d.ts +0 -5
  126. package/dist/signals/globals.d.ts.map +1 -1
  127. package/dist/signals/globals.js +0 -6
  128. package/dist/signals/globals.js.map +1 -1
  129. package/dist/signals/index.d.ts +4 -4
  130. package/dist/signals/index.d.ts.map +1 -1
  131. package/dist/signals/index.js +4 -4
  132. package/dist/signals/index.js.map +1 -1
  133. package/dist/signals/{for.d.ts → jsx.d.ts} +8 -1
  134. package/dist/signals/jsx.d.ts.map +1 -0
  135. package/dist/signals/{for.js → jsx.js} +4 -1
  136. package/dist/signals/jsx.js.map +1 -0
  137. package/dist/signals/tracking.d.ts +23 -0
  138. package/dist/signals/tracking.d.ts.map +1 -0
  139. package/dist/signals/tracking.js +51 -0
  140. package/dist/signals/tracking.js.map +1 -0
  141. package/dist/signals/types.d.ts +1 -1
  142. package/dist/signals/types.d.ts.map +1 -1
  143. package/dist/signals/utils.d.ts +2 -1
  144. package/dist/signals/utils.d.ts.map +1 -1
  145. package/dist/signals/utils.js +9 -2
  146. package/dist/signals/utils.js.map +1 -1
  147. package/dist/ssr/client.d.ts +3 -3
  148. package/dist/ssr/client.d.ts.map +1 -1
  149. package/dist/ssr/client.js.map +1 -1
  150. package/dist/ssr/server.js +1 -1
  151. package/dist/ssr/server.js.map +1 -1
  152. package/dist/statefulPromise.d.ts +22 -0
  153. package/dist/statefulPromise.d.ts.map +1 -0
  154. package/dist/statefulPromise.js +94 -0
  155. package/dist/statefulPromise.js.map +1 -0
  156. package/dist/types.d.ts +36 -50
  157. package/dist/types.d.ts.map +1 -1
  158. package/dist/types.dom.d.ts +4 -7
  159. package/dist/types.dom.d.ts.map +1 -1
  160. package/dist/types.utils.d.ts +3 -4
  161. package/dist/types.utils.d.ts.map +1 -1
  162. package/dist/utils/vdom.d.ts +8 -6
  163. package/dist/utils/vdom.d.ts.map +1 -1
  164. package/dist/utils/vdom.js +32 -9
  165. package/dist/utils/vdom.js.map +1 -1
  166. package/dist/viewTransitions.d.ts +7 -0
  167. package/dist/viewTransitions.d.ts.map +1 -0
  168. package/dist/viewTransitions.js +71 -0
  169. package/dist/viewTransitions.js.map +1 -0
  170. package/package.json +1 -1
  171. package/src/{appContext.ts → appHandle.ts} +21 -16
  172. package/src/components/derive.ts +74 -69
  173. package/src/components/index.ts +0 -1
  174. package/src/components/lazy.ts +5 -4
  175. package/src/components/portal.ts +2 -3
  176. package/src/components/transition.ts +33 -35
  177. package/src/constants.ts +0 -8
  178. package/src/context.ts +30 -23
  179. package/src/devtools.ts +16 -0
  180. package/src/dom.ts +29 -63
  181. package/src/globalContext.ts +57 -74
  182. package/src/globals.ts +1 -5
  183. package/src/{recursiveRender.ts → headlessRender.ts} +18 -18
  184. package/src/hmr.ts +29 -38
  185. package/src/hooks/index.ts +3 -14
  186. package/src/hooks/onBeforeMount.ts +12 -0
  187. package/src/hooks/onCleanup.ts +15 -0
  188. package/src/hooks/onMount.ts +12 -0
  189. package/src/hooks/utils.ts +28 -238
  190. package/src/index.ts +14 -6
  191. package/src/profiling.ts +22 -20
  192. package/src/reconciler.ts +18 -30
  193. package/src/ref.ts +6 -0
  194. package/src/renderToString.ts +1 -1
  195. package/src/router/context.ts +1 -2
  196. package/src/router/fileRouter.ts +23 -13
  197. package/src/router/fileRouterController.ts +72 -64
  198. package/src/router/link.ts +11 -25
  199. package/src/router/server/index.ts +24 -13
  200. package/src/router/types.ts +15 -8
  201. package/src/scheduler.ts +74 -71
  202. package/src/signals/base.ts +12 -41
  203. package/src/signals/computed.ts +1 -62
  204. package/src/signals/effect.ts +95 -48
  205. package/src/signals/globals.ts +0 -7
  206. package/src/signals/index.ts +4 -4
  207. package/src/signals/{for.ts → jsx.ts} +10 -0
  208. package/src/signals/tracking.ts +69 -0
  209. package/src/signals/types.ts +1 -1
  210. package/src/signals/utils.ts +9 -1
  211. package/src/ssr/client.ts +4 -4
  212. package/src/ssr/server.ts +2 -2
  213. package/src/statefulPromise.ts +136 -0
  214. package/src/types.dom.ts +4 -8
  215. package/src/types.ts +45 -58
  216. package/src/types.utils.ts +3 -4
  217. package/src/utils/vdom.ts +44 -15
  218. package/src/viewTransitions.ts +88 -0
  219. package/dist/appContext.d.ts.map +0 -1
  220. package/dist/appContext.js.map +0 -1
  221. package/dist/components/memo.d.ts +0 -10
  222. package/dist/components/memo.d.ts.map +0 -1
  223. package/dist/components/memo.js +0 -23
  224. package/dist/components/memo.js.map +0 -1
  225. package/dist/form/index.d.ts +0 -4
  226. package/dist/form/index.d.ts.map +0 -1
  227. package/dist/form/index.js +0 -518
  228. package/dist/form/index.js.map +0 -1
  229. package/dist/form/types.d.ts +0 -122
  230. package/dist/form/types.d.ts.map +0 -1
  231. package/dist/form/types.js +0 -2
  232. package/dist/form/types.js.map +0 -1
  233. package/dist/form/utils.d.ts +0 -3
  234. package/dist/form/utils.d.ts.map +0 -1
  235. package/dist/form/utils.js +0 -16
  236. package/dist/form/utils.js.map +0 -1
  237. package/dist/hooks/useAsync.d.ts +0 -18
  238. package/dist/hooks/useAsync.d.ts.map +0 -1
  239. package/dist/hooks/useAsync.js +0 -96
  240. package/dist/hooks/useAsync.js.map +0 -1
  241. package/dist/hooks/useCallback.d.ts +0 -7
  242. package/dist/hooks/useCallback.d.ts.map +0 -1
  243. package/dist/hooks/useCallback.js +0 -30
  244. package/dist/hooks/useCallback.js.map +0 -1
  245. package/dist/hooks/useContext.d.ts +0 -7
  246. package/dist/hooks/useContext.d.ts.map +0 -1
  247. package/dist/hooks/useContext.js +0 -59
  248. package/dist/hooks/useContext.js.map +0 -1
  249. package/dist/hooks/useEffect.d.ts +0 -8
  250. package/dist/hooks/useEffect.d.ts.map +0 -1
  251. package/dist/hooks/useEffect.js +0 -34
  252. package/dist/hooks/useEffect.js.map +0 -1
  253. package/dist/hooks/useEffectEvent.d.ts +0 -8
  254. package/dist/hooks/useEffectEvent.d.ts.map +0 -1
  255. package/dist/hooks/useEffectEvent.js +0 -23
  256. package/dist/hooks/useEffectEvent.js.map +0 -1
  257. package/dist/hooks/useId.d.ts +0 -8
  258. package/dist/hooks/useId.d.ts.map +0 -1
  259. package/dist/hooks/useId.js +0 -35
  260. package/dist/hooks/useId.js.map +0 -1
  261. package/dist/hooks/useLayoutEffect.d.ts +0 -8
  262. package/dist/hooks/useLayoutEffect.d.ts.map +0 -1
  263. package/dist/hooks/useLayoutEffect.js +0 -34
  264. package/dist/hooks/useLayoutEffect.js.map +0 -1
  265. package/dist/hooks/useMemo.d.ts +0 -8
  266. package/dist/hooks/useMemo.d.ts.map +0 -1
  267. package/dist/hooks/useMemo.js +0 -31
  268. package/dist/hooks/useMemo.js.map +0 -1
  269. package/dist/hooks/usePromise.d.ts +0 -8
  270. package/dist/hooks/usePromise.d.ts.map +0 -1
  271. package/dist/hooks/usePromise.js +0 -90
  272. package/dist/hooks/usePromise.js.map +0 -1
  273. package/dist/hooks/useReducer.d.ts +0 -7
  274. package/dist/hooks/useReducer.d.ts.map +0 -1
  275. package/dist/hooks/useReducer.js +0 -44
  276. package/dist/hooks/useReducer.js.map +0 -1
  277. package/dist/hooks/useRef.d.ts +0 -10
  278. package/dist/hooks/useRef.d.ts.map +0 -1
  279. package/dist/hooks/useRef.js +0 -29
  280. package/dist/hooks/useRef.js.map +0 -1
  281. package/dist/hooks/useState.d.ts +0 -7
  282. package/dist/hooks/useState.d.ts.map +0 -1
  283. package/dist/hooks/useState.js +0 -54
  284. package/dist/hooks/useState.js.map +0 -1
  285. package/dist/hooks/useSyncExternalStore.d.ts +0 -8
  286. package/dist/hooks/useSyncExternalStore.d.ts.map +0 -1
  287. package/dist/hooks/useSyncExternalStore.js +0 -50
  288. package/dist/hooks/useSyncExternalStore.js.map +0 -1
  289. package/dist/hooks/useViewTransition.d.ts +0 -10
  290. package/dist/hooks/useViewTransition.d.ts.map +0 -1
  291. package/dist/hooks/useViewTransition.js +0 -27
  292. package/dist/hooks/useViewTransition.js.map +0 -1
  293. package/dist/recursiveRender.d.ts +0 -7
  294. package/dist/recursiveRender.d.ts.map +0 -1
  295. package/dist/recursiveRender.js.map +0 -1
  296. package/dist/signals/for.d.ts.map +0 -1
  297. package/dist/signals/for.js.map +0 -1
  298. package/dist/signals/watch.d.ts +0 -21
  299. package/dist/signals/watch.d.ts.map +0 -1
  300. package/dist/signals/watch.js +0 -86
  301. package/dist/signals/watch.js.map +0 -1
  302. package/dist/store.d.ts +0 -28
  303. package/dist/store.d.ts.map +0 -1
  304. package/dist/store.js +0 -166
  305. package/dist/store.js.map +0 -1
  306. package/dist/swr.d.ts +0 -63
  307. package/dist/swr.d.ts.map +0 -1
  308. package/dist/swr.js +0 -236
  309. package/dist/swr.js.map +0 -1
  310. package/dist/utils/promise.d.ts +0 -16
  311. package/dist/utils/promise.d.ts.map +0 -1
  312. package/dist/utils/promise.js +0 -14
  313. package/dist/utils/promise.js.map +0 -1
  314. package/src/components/memo.ts +0 -39
  315. package/src/form/index.ts +0 -676
  316. package/src/form/types.ts +0 -262
  317. package/src/form/utils.ts +0 -19
  318. package/src/hooks/useAsync.ts +0 -121
  319. package/src/hooks/useCallback.ts +0 -32
  320. package/src/hooks/useContext.ts +0 -79
  321. package/src/hooks/useEffect.ts +0 -40
  322. package/src/hooks/useEffectEvent.ts +0 -24
  323. package/src/hooks/useId.ts +0 -42
  324. package/src/hooks/useLayoutEffect.ts +0 -43
  325. package/src/hooks/useMemo.ts +0 -34
  326. package/src/hooks/usePromise.ts +0 -126
  327. package/src/hooks/useReducer.ts +0 -50
  328. package/src/hooks/useRef.ts +0 -41
  329. package/src/hooks/useState.ts +0 -62
  330. package/src/hooks/useSyncExternalStore.ts +0 -59
  331. package/src/hooks/useViewTransition.ts +0 -25
  332. package/src/signals/watch.ts +0 -139
  333. package/src/store.ts +0 -245
  334. package/src/swr.ts +0 -351
  335. package/src/utils/promise.ts +0 -26
@@ -1,7 +1,7 @@
1
- import { Signal } from "../signals/base.js"
2
- import { watch } from "../signals/watch.js"
1
+ import { signal, Signal } from "../signals/base.js"
2
+ import { effect } from "../signals/effect.js"
3
3
  import { __DEV__ } from "../env.js"
4
- import { flushSync, nextIdle } from "../scheduler.js"
4
+ import { nextIdle } from "../scheduler.js"
5
5
  import { ReloadOptions, type FileRouterContextType } from "./context.js"
6
6
  import { FileRouterDataLoadError } from "./errors.js"
7
7
  import { fileRouterInstance, fileRouterRoute, routerCache } from "./globals.js"
@@ -9,7 +9,9 @@ import type {
9
9
  FileRouterConfig,
10
10
  PageConfig,
11
11
  PageDataLoaderConfig,
12
+ PageDataLoaderContext,
12
13
  PageProps,
14
+ RouteParams,
13
15
  RouteQuery,
14
16
  RouterState,
15
17
  } from "./types.js"
@@ -31,6 +33,7 @@ import {
31
33
  } from "./utils/index.js"
32
34
  import { RouterCache, type CacheKey } from "./cache.js"
33
35
  import { scrollStack } from "./scrollStack.js"
36
+ import { ViewTransitions } from "../viewTransitions.js"
34
37
 
35
38
  interface PageConfigWithLoader<T = unknown> extends PageConfig {
36
39
  loader: PageDataLoaderConfig<T>
@@ -62,18 +65,18 @@ export class FileRouterController {
62
65
  constructor() {
63
66
  routerCache.current ??= new RouterCache()
64
67
  this.abortController = new AbortController()
65
- this.currentPage = new Signal(null)
66
- this.currentPageProps = new Signal({})
67
- this.currentLayouts = new Signal([])
68
+ this.currentPage = signal(null)
69
+ this.currentPageProps = signal({})
70
+ this.currentLayouts = signal([])
68
71
  this.enableTransitions = false
69
72
  this.historyIndex = 0
70
73
  this.layouts = {}
71
74
  this.pages = {}
72
75
  this.state = {
73
- pathname: window.location.pathname,
74
- hash: window.location.hash,
75
- params: {},
76
- query: {},
76
+ pathname: signal(window.location.pathname),
77
+ hash: signal(window.location.hash),
78
+ params: signal<RouteParams>({}),
79
+ query: signal<RouteQuery>({}),
77
80
  signal: this.abortController.signal,
78
81
  }
79
82
  this.contextValue = this.createContextValue()
@@ -99,10 +102,11 @@ export class FileRouterController {
99
102
  // Check cache first if caching is enabled
100
103
  let cachedData = null
101
104
  if (loader.mode !== "static" && loader.cache) {
105
+ const { pathname, params, query } = this.state
102
106
  const cacheKey: CacheKey = {
103
- path: this.state.pathname,
104
- params: this.state.params,
105
- query: this.state.query,
107
+ path: pathname.peek(),
108
+ params: params.peek(),
109
+ query: query.peek(),
106
110
  }
107
111
  cachedData = routerCache.current!.get(cacheKey, loader.cache)
108
112
  }
@@ -130,10 +134,18 @@ export class FileRouterController {
130
134
  this.currentPageProps.value = props
131
135
  })
132
136
 
137
+ const { pathname, hash, params, query, signal } = this.state
138
+
133
139
  this.loadRouteData(
134
140
  config as PageConfigWithLoader,
135
141
  props,
136
- this.state,
142
+ {
143
+ pathname: pathname.peek(),
144
+ hash: hash.peek(),
145
+ params: params.peek(),
146
+ query: query.peek(),
147
+ signal,
148
+ },
137
149
  transition
138
150
  )
139
151
  }
@@ -150,15 +162,12 @@ export class FileRouterController {
150
162
  },
151
163
  navigate: this.navigate.bind(this),
152
164
  reload: () => {
153
- this.invalidate(this.state.pathname)
165
+ this.invalidate(this.state.pathname.peek())
154
166
  return this.loadRoute()
155
167
  },
156
168
  subscribe: (callback) => {
157
- const watcher = watch(
158
- [this.currentPage, this.currentPageProps],
159
- callback
160
- )
161
- return () => watcher.stop()
169
+ const e = effect([this.currentPage, this.currentPageProps], callback)
170
+ return () => e.stop()
162
171
  },
163
172
  }
164
173
  }
@@ -192,13 +201,11 @@ export class FileRouterController {
192
201
  query,
193
202
  cacheData,
194
203
  } = preloaded
195
- this.state = {
196
- params,
197
- query,
198
- pathname: window.location.pathname,
199
- hash: window.location.hash,
200
- signal: this.abortController.signal,
201
- }
204
+ this.state.pathname.value = window.location.pathname
205
+ this.state.hash.value = window.location.hash
206
+ this.state.params.value = params
207
+ this.state.query.value = query
208
+ this.state.signal = this.abortController.signal
202
209
  this.currentPage.value = {
203
210
  component: page.default,
204
211
  config: page.config,
@@ -222,11 +229,14 @@ export class FileRouterController {
222
229
  ((loader.mode !== "static" && pageProps.loading === true) || __DEV__)
223
230
  ) {
224
231
  if (cacheData === null) {
225
- this.loadRouteData(
226
- page.config as PageConfigWithLoader,
227
- pageProps,
228
- this.state
229
- )
232
+ const { pathname, hash, params, query, signal } = this.state
233
+ this.loadRouteData(page.config as PageConfigWithLoader, pageProps, {
234
+ pathname: pathname.peek(),
235
+ hash: hash.peek(),
236
+ params: params.peek(),
237
+ query: query.peek(),
238
+ signal,
239
+ })
230
240
  } else {
231
241
  nextIdle(() => {
232
242
  const props = {
@@ -385,7 +395,7 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
385
395
  )
386
396
  }
387
397
 
388
- const routerState: RouterState = {
398
+ const loaderContext: PageDataLoaderContext = {
389
399
  pathname: path,
390
400
  hash: window.location.hash,
391
401
  params,
@@ -408,9 +418,9 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
408
418
  let cachedData = null
409
419
  if (loader.mode !== "static" && loader.cache) {
410
420
  const cacheKey: CacheKey = {
411
- path: routerState.pathname,
412
- params: routerState.params,
413
- query: routerState.query,
421
+ path: loaderContext.pathname,
422
+ params: loaderContext.params,
423
+ query: loaderContext.query,
414
424
  }
415
425
  cachedData = routerCache.current!.get(cacheKey, loader.cache)
416
426
  }
@@ -435,7 +445,7 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
435
445
  this.loadRouteData(
436
446
  config as PageConfigWithLoader,
437
447
  props,
438
- routerState,
448
+ loaderContext,
439
449
  enableTransition
440
450
  )
441
451
  }
@@ -456,8 +466,11 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
456
466
  }
457
467
 
458
468
  return handleStateTransition(signal, enableTransition, () => {
459
- this.state = routerState
460
- this.contextValue = this.createContextValue()
469
+ this.state.pathname.value = path
470
+ this.state.hash.value = window.location.hash
471
+ this.state.params.value = params
472
+ this.state.query.value = query
473
+ this.state.signal = signal
461
474
  this.currentPage.value = {
462
475
  component: page.default,
463
476
  config,
@@ -477,22 +490,22 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
477
490
  private async loadRouteData(
478
491
  config: PageConfigWithLoader,
479
492
  props: Record<string, unknown>,
480
- routerState: RouterState,
493
+ context: PageDataLoaderContext,
481
494
  enableTransition = this.enableTransitions
482
495
  ) {
483
496
  const { loader } = config
484
497
 
485
498
  // Load data from loader (cache check is now done earlier in loadRoute)
486
499
  loader
487
- .load(routerState)
500
+ .load(context)
488
501
  .then(
489
502
  (data) => {
490
503
  // Cache the data if caching is enabled
491
504
  if (loader.mode !== "static" && loader.cache) {
492
505
  const cacheKey: CacheKey = {
493
- path: routerState.pathname,
494
- params: routerState.params,
495
- query: routerState.query,
506
+ path: context.pathname,
507
+ params: context.params,
508
+ query: context.query,
496
509
  }
497
510
  routerCache.current!.set(cacheKey, data, loader.cache)
498
511
  }
@@ -508,15 +521,15 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
508
521
  data: null,
509
522
  error: new FileRouterDataLoadError(error),
510
523
  loading: false,
511
- }) satisfies PageProps<PageConfig<unknown>>
524
+ } satisfies PageProps<PageConfig<unknown>>)
512
525
  )
513
526
  .then((state) => {
514
- if (routerState.signal.aborted) return
527
+ if (context.signal.aborted) return
515
528
 
516
529
  const transition =
517
530
  (loader.mode !== "static" && loader.transition) ?? enableTransition
518
531
 
519
- handleStateTransition(routerState.signal, transition, () => {
532
+ handleStateTransition(context.signal, transition, () => {
520
533
  this.currentPageProps.value = {
521
534
  ...props,
522
535
  ...state,
@@ -530,7 +543,7 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
530
543
  routerCache.current!.invalidate(...paths)
531
544
 
532
545
  // Check if current page matches any invalidated paths
533
- const currentPath = this.state.pathname
546
+ const currentPath = this.state.pathname.peek()
534
547
  const shouldRefresh = routerCache.current!.pathMatchesPattern(
535
548
  currentPath,
536
549
  paths
@@ -548,7 +561,8 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
548
561
  ) {
549
562
  const url = new URL(path, "http://localhost")
550
563
  const { hash: nextHash, pathname: nextPath } = url
551
- const { hash: prevHash, pathname: prevPath } = this.state
564
+ const prevHash = this.state.hash.peek()
565
+ const prevPath = this.state.pathname.peek()
552
566
  if (nextHash === prevHash && nextPath === prevPath) {
553
567
  return
554
568
  }
@@ -598,11 +612,11 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
598
612
 
599
613
  private setQuery(query: RouteQuery, options?: { replace?: boolean }) {
600
614
  const queryString = buildQueryString(query)
601
- const newUrl = `${this.state.pathname}${
615
+ const newUrl = `${this.state.pathname.peek()}${
602
616
  queryString ? `?${queryString}` : ""
603
617
  }`
604
618
  this.updateHistoryState(newUrl, options)
605
- this.state = { ...this.state, query }
619
+ this.state.query.value = query
606
620
  return this.loadRoute()
607
621
  }
608
622
 
@@ -612,11 +626,11 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
612
626
  } else if (hash.length && !hash.startsWith("#")) {
613
627
  hash = `#${hash}`
614
628
  }
615
- if (hash === this.state.hash) {
629
+ if (hash === this.state.hash.peek()) {
616
630
  return
617
631
  }
618
- this.updateHistoryState(`${this.state.pathname}${hash}`, options)
619
- this.state = { ...this.state, hash }
632
+ this.updateHistoryState(`${this.state.pathname.peek()}${hash}`, options)
633
+ this.state.hash.value = hash
620
634
  return this.loadRoute()
621
635
  }
622
636
 
@@ -659,13 +673,13 @@ See https://kirujs.dev/docs/api/file-router#404 for more information.`
659
673
  }
660
674
  },
661
675
  get state() {
662
- return { ...__this.state }
676
+ return __this.state
663
677
  },
664
678
  navigate: this.navigate.bind(this),
665
679
  prefetchRouteModules: this.prefetchRouteModules.bind(this),
666
680
  reload: async (options?: ReloadOptions) => {
667
681
  if (options?.invalidate ?? true) {
668
- this.invalidate(this.state.pathname)
682
+ this.invalidate(this.state.pathname.peek())
669
683
  }
670
684
  return this.loadRoute(void 0, void 0, options?.transition)
671
685
  },
@@ -698,19 +712,13 @@ async function handleStateTransition(
698
712
  enableTransition: boolean,
699
713
  callback: () => void
700
714
  ) {
701
- if (!enableTransition || typeof document.startViewTransition !== "function") {
715
+ if (!enableTransition) {
702
716
  return new Promise<void>((resolve) => {
703
717
  callback()
704
718
  nextIdle(resolve)
705
719
  })
706
720
  }
707
- const vt = document.startViewTransition(() => {
708
- callback()
709
- flushSync()
710
- })
711
-
712
- signal.addEventListener("abort", () => vt.skipTransition())
713
- await vt.ready
721
+ await ViewTransitions.run(callback, { signal })
714
722
  }
715
723
 
716
724
  function validateRoutes(pageMap: FormattedViteImportMap) {
@@ -1,6 +1,5 @@
1
1
  import type { ElementProps } from "../types"
2
2
  import { createElement } from "../element.js"
3
- import { useCallback } from "../hooks/index.js"
4
3
  import { useFileRouter } from "./context.js"
5
4
 
6
5
  export interface LinkProps extends ElementProps<"a"> {
@@ -40,40 +39,27 @@ export const Link: Kiru.FC<LinkProps> = ({
40
39
  const { navigate, prefetchRouteModules, baseUrl } = useFileRouter()
41
40
 
42
41
  const href = baseUrl + to
43
- const handleMouseOver = useCallback(
44
- (e: Kiru.MouseEvent<HTMLAnchorElement>) => {
42
+
43
+ return createElement("a", {
44
+ href: href,
45
+ onclick: (e: Kiru.MouseEvent<HTMLAnchorElement>) => {
46
+ onclick?.(e)
47
+ if (e.defaultPrevented) return
48
+ e.preventDefault()
49
+ navigate(href, { replace, transition })
50
+ },
51
+ onmouseover: (e: Kiru.MouseEvent<HTMLAnchorElement>) => {
45
52
  if (prefetchJs !== false) {
46
53
  prefetchRouteModules(href)
47
54
  }
48
55
  onmouseover?.(e)
49
56
  },
50
- [onmouseover, href]
51
- )
52
- const handleFocus = useCallback(
53
- (e: Kiru.FocusEvent<HTMLAnchorElement>) => {
57
+ onfocus: (e: Kiru.FocusEvent<HTMLAnchorElement>) => {
54
58
  if (prefetchJs !== false) {
55
59
  prefetchRouteModules(href)
56
60
  }
57
61
  onfocus?.(e)
58
62
  },
59
- [onfocus, href]
60
- )
61
-
62
- const handleClick = useCallback(
63
- (e: Kiru.MouseEvent<HTMLAnchorElement>) => {
64
- onclick?.(e)
65
- if (e.defaultPrevented) return
66
- e.preventDefault()
67
- navigate(href, { replace, transition })
68
- },
69
- [onclick, navigate, href, replace, transition]
70
- )
71
-
72
- return createElement("a", {
73
- href: href,
74
- onclick: handleClick,
75
- onmouseover: handleMouseOver,
76
- onfocus: handleFocus,
77
63
  ...props,
78
64
  })
79
65
  }
@@ -8,7 +8,13 @@ import {
8
8
  wrapWithLayouts,
9
9
  } from "../utils/index.js"
10
10
  import { RouterContext } from "../context.js"
11
- import type { PageConfig, PageProps, RouterState } from "../types.js"
11
+ import { signal, Signal } from "../../signals/base.js"
12
+ import type {
13
+ PageConfig,
14
+ PageDataLoaderContext,
15
+ PageProps,
16
+ RouterState,
17
+ } from "../types.js"
12
18
  import { FormattedViteImportMap, PageModule } from "../types.internal.js"
13
19
  import { __DEV__ } from "../../env.js"
14
20
  import { FileRouterDataLoadError } from "../errors.js"
@@ -86,7 +92,7 @@ export async function render(
86
92
  if (config.loader.mode !== "static" || __DEV__) {
87
93
  props = { loading: true, data: null, error: null }
88
94
  } else {
89
- const routerState: RouterState = {
95
+ const loaderContext: PageDataLoaderContext = {
90
96
  pathname: u.pathname,
91
97
  hash: "",
92
98
  params,
@@ -100,7 +106,7 @@ export async function render(
100
106
  }, 10000)
101
107
 
102
108
  try {
103
- const data = await config.loader.load(routerState)
109
+ const data = await config.loader.load(loaderContext)
104
110
  props = {
105
111
  data,
106
112
  error: null,
@@ -127,6 +133,14 @@ export async function render(
127
133
  props
128
134
  )
129
135
 
136
+ const routerState: RouterState = {
137
+ pathname: signal(u.pathname),
138
+ hash: signal(""),
139
+ params: signal(params),
140
+ query: signal(query),
141
+ signal: abortController.signal,
142
+ }
143
+
130
144
  let documentShell = renderToString(createElement(ctx.Document))
131
145
 
132
146
  if (
@@ -138,16 +152,11 @@ export async function render(
138
152
  )
139
153
  }
140
154
 
141
- const app = createElement(RouterContext.Provider, {
155
+ const app = createElement(RouterContext, {
142
156
  children: Fragment({ children }),
143
157
  value: {
144
158
  baseUrl: ctx.baseUrl.slice(0, -1),
145
- state: {
146
- params,
147
- query,
148
- pathname: u.pathname,
149
- signal: abortController.signal, // Server-side signal (not abortable)
150
- } as RouterState,
159
+ state: routerState,
151
160
  },
152
161
  })
153
162
 
@@ -175,13 +184,15 @@ export async function render(
175
184
  documentShell = documentShell.replaceAll("<kiru-head-outlet>", "")
176
185
  }
177
186
 
187
+ Object.values(routerState).forEach(
188
+ (s) => Signal.isSignal(s) && Signal.dispose(s)
189
+ )
190
+
178
191
  const [prePageOutlet, postPageOutlet] =
179
192
  documentShell.split("<kiru-body-outlet>")
180
193
 
181
- // console.log("immediate", immediate)
182
-
183
194
  return {
184
- status: is404Route ? 404 : (result?.status ?? 200),
195
+ status: is404Route ? 404 : result?.status ?? 200,
185
196
  body: `<!doctype html>${prePageOutlet}<body>${pageOutletContent}</body>${postPageOutlet}`,
186
197
  }
187
198
  }
@@ -74,23 +74,23 @@ export interface RouterState {
74
74
  * @example
75
75
  * "/users/[id]" -> "/users/123"
76
76
  */
77
- pathname: string
77
+ pathname: Kiru.Signal<string>
78
78
  /**
79
79
  * The current hash
80
80
  * @example
81
81
  * "/users/123#profile" -> "#profile"
82
82
  */
83
- hash: string
83
+ hash: Kiru.Signal<string>
84
84
  /**
85
85
  * The current route params
86
86
  * @example
87
87
  * "/foo/[id]/page.tsx" -> { id: "123" }
88
88
  */
89
- params: RouteParams
89
+ params: Kiru.Signal<RouteParams>
90
90
  /**
91
91
  * The current route query
92
92
  */
93
- query: RouteQuery
93
+ query: Kiru.Signal<RouteQuery>
94
94
  /**
95
95
  * The abort signal for the current route, aborted and
96
96
  * renewed each time the route changes or reloads
@@ -98,7 +98,13 @@ export interface RouterState {
98
98
  signal: AbortSignal
99
99
  }
100
100
 
101
- type PageDataLoaderContext = RouterState & {}
101
+ export interface PageDataLoaderContext {
102
+ pathname: string
103
+ hash: string
104
+ params: RouteParams
105
+ query: RouteQuery
106
+ signal: AbortSignal
107
+ }
102
108
 
103
109
  export interface PageDataLoaderCacheConfig {
104
110
  type: "memory" | "localStorage" | "sessionStorage"
@@ -161,6 +167,7 @@ export interface PageConfig<T = unknown> {
161
167
  generateStaticParams?: () => RouteParams[] | Promise<RouteParams[]>
162
168
  }
163
169
 
164
- export type PageProps<T extends PageConfig<any>> = T extends PageConfig<infer U>
165
- ? AsyncTaskState<U, FileRouterDataLoadError>
166
- : {}
170
+ export type PageProps<T extends PageConfig<any>> =
171
+ T extends PageConfig<infer U>
172
+ ? AsyncTaskState<U, FileRouterDataLoadError>
173
+ : {}