kiru 0.54.0-preview.0 → 0.54.0

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 (178) hide show
  1. package/dist/components/memo.d.ts +1 -3
  2. package/dist/components/memo.d.ts.map +1 -1
  3. package/dist/components/memo.js +2 -2
  4. package/dist/components/memo.js.map +1 -1
  5. package/dist/context.d.ts.map +1 -1
  6. package/dist/context.js +1 -23
  7. package/dist/context.js.map +1 -1
  8. package/dist/dom.d.ts.map +1 -1
  9. package/dist/dom.js +109 -72
  10. package/dist/dom.js.map +1 -1
  11. package/dist/error.d.ts.map +1 -1
  12. package/dist/error.js +2 -4
  13. package/dist/error.js.map +1 -1
  14. package/dist/form/index.d.ts.map +1 -1
  15. package/dist/form/index.js +6 -10
  16. package/dist/form/index.js.map +1 -1
  17. package/dist/globals.d.ts +1 -1
  18. package/dist/globals.d.ts.map +1 -1
  19. package/dist/globals.js.map +1 -1
  20. package/dist/hmr.d.ts +1 -0
  21. package/dist/hmr.d.ts.map +1 -1
  22. package/dist/hmr.js +11 -3
  23. package/dist/hmr.js.map +1 -1
  24. package/dist/hooks/useEffectEvent.d.ts.map +1 -1
  25. package/dist/hooks/useEffectEvent.js.map +1 -1
  26. package/dist/hooks/usePromise.d.ts.map +1 -1
  27. package/dist/hooks/usePromise.js.map +1 -1
  28. package/dist/hooks/utils.d.ts.map +1 -1
  29. package/dist/hooks/utils.js +10 -10
  30. package/dist/hooks/utils.js.map +1 -1
  31. package/dist/hydration.d.ts +6 -13
  32. package/dist/hydration.d.ts.map +1 -1
  33. package/dist/hydration.js +20 -50
  34. package/dist/hydration.js.map +1 -1
  35. package/dist/reconciler.d.ts.map +1 -1
  36. package/dist/reconciler.js +3 -6
  37. package/dist/reconciler.js.map +1 -1
  38. package/dist/recursiveRender.d.ts.map +1 -1
  39. package/dist/recursiveRender.js +9 -8
  40. package/dist/recursiveRender.js.map +1 -1
  41. package/dist/renderToString.d.ts.map +1 -1
  42. package/dist/renderToString.js.map +1 -1
  43. package/dist/router/client/index.d.ts +2 -4
  44. package/dist/router/client/index.d.ts.map +1 -1
  45. package/dist/router/client/index.js +11 -49
  46. package/dist/router/client/index.js.map +1 -1
  47. package/dist/router/context.d.ts +5 -2
  48. package/dist/router/context.d.ts.map +1 -1
  49. package/dist/router/context.js +1 -5
  50. package/dist/router/context.js.map +1 -1
  51. package/dist/router/fileRouter.d.ts.map +1 -1
  52. package/dist/router/fileRouter.js +2 -4
  53. package/dist/router/fileRouter.js.map +1 -1
  54. package/dist/router/fileRouterController.d.ts +2 -2
  55. package/dist/router/fileRouterController.d.ts.map +1 -1
  56. package/dist/router/fileRouterController.js +39 -101
  57. package/dist/router/fileRouterController.js.map +1 -1
  58. package/dist/router/globals.d.ts +0 -3
  59. package/dist/router/globals.d.ts.map +1 -1
  60. package/dist/router/globals.js +0 -3
  61. package/dist/router/globals.js.map +1 -1
  62. package/dist/router/head.d.ts.map +1 -1
  63. package/dist/router/head.js +7 -5
  64. package/dist/router/head.js.map +1 -1
  65. package/dist/router/index.d.ts +1 -2
  66. package/dist/router/index.d.ts.map +1 -1
  67. package/dist/router/index.js +1 -2
  68. package/dist/router/index.js.map +1 -1
  69. package/dist/router/link.js +3 -3
  70. package/dist/router/link.js.map +1 -1
  71. package/dist/router/{ssg → server}/index.d.ts +3 -4
  72. package/dist/router/server/index.d.ts.map +1 -0
  73. package/dist/router/{ssg → server}/index.js +5 -8
  74. package/dist/router/server/index.js.map +1 -0
  75. package/dist/router/types.d.ts +4 -37
  76. package/dist/router/types.d.ts.map +1 -1
  77. package/dist/router/types.internal.d.ts +0 -4
  78. package/dist/router/types.internal.d.ts.map +1 -1
  79. package/dist/router/utils/index.d.ts +3 -8
  80. package/dist/router/utils/index.d.ts.map +1 -1
  81. package/dist/router/utils/index.js +8 -40
  82. package/dist/router/utils/index.js.map +1 -1
  83. package/dist/scheduler.d.ts.map +1 -1
  84. package/dist/scheduler.js +60 -53
  85. package/dist/scheduler.js.map +1 -1
  86. package/dist/signals/base.d.ts +0 -2
  87. package/dist/signals/base.d.ts.map +1 -1
  88. package/dist/signals/base.js +0 -6
  89. package/dist/signals/base.js.map +1 -1
  90. package/dist/signals/computed.d.ts +3 -0
  91. package/dist/signals/computed.d.ts.map +1 -1
  92. package/dist/signals/computed.js +29 -20
  93. package/dist/signals/computed.js.map +1 -1
  94. package/dist/signals/for.d.ts +3 -3
  95. package/dist/signals/for.d.ts.map +1 -1
  96. package/dist/signals/for.js +2 -1
  97. package/dist/signals/for.js.map +1 -1
  98. package/dist/signals/utils.d.ts.map +1 -1
  99. package/dist/signals/utils.js +2 -1
  100. package/dist/signals/utils.js.map +1 -1
  101. package/dist/signals/watch.d.ts.map +1 -1
  102. package/dist/signals/watch.js +18 -22
  103. package/dist/signals/watch.js.map +1 -1
  104. package/dist/ssr/client.d.ts +1 -1
  105. package/dist/ssr/client.d.ts.map +1 -1
  106. package/dist/ssr/client.js +0 -2
  107. package/dist/ssr/client.js.map +1 -1
  108. package/dist/ssr/server.d.ts +2 -1
  109. package/dist/ssr/server.d.ts.map +1 -1
  110. package/dist/ssr/server.js +19 -16
  111. package/dist/ssr/server.js.map +1 -1
  112. package/dist/types.d.ts +0 -7
  113. package/dist/types.d.ts.map +1 -1
  114. package/dist/types.dom.d.ts +3 -3
  115. package/dist/types.dom.d.ts.map +1 -1
  116. package/dist/utils/format.d.ts +1 -2
  117. package/dist/utils/format.d.ts.map +1 -1
  118. package/dist/utils/format.js +1 -4
  119. package/dist/utils/format.js.map +1 -1
  120. package/dist/utils/runtime.d.ts +3 -2
  121. package/dist/utils/runtime.d.ts.map +1 -1
  122. package/dist/utils/runtime.js +5 -2
  123. package/dist/utils/runtime.js.map +1 -1
  124. package/dist/utils/vdom.d.ts.map +1 -1
  125. package/dist/utils/vdom.js +2 -2
  126. package/dist/utils/vdom.js.map +1 -1
  127. package/package.json +4 -8
  128. package/src/components/memo.ts +3 -11
  129. package/src/context.ts +1 -24
  130. package/src/dom.ts +145 -96
  131. package/src/error.ts +2 -4
  132. package/src/form/index.ts +6 -9
  133. package/src/globals.ts +1 -1
  134. package/src/hmr.ts +14 -5
  135. package/src/hooks/useEffectEvent.ts +0 -1
  136. package/src/hooks/usePromise.ts +0 -1
  137. package/src/hooks/utils.ts +12 -12
  138. package/src/hydration.ts +21 -57
  139. package/src/reconciler.ts +2 -6
  140. package/src/recursiveRender.ts +10 -9
  141. package/src/renderToString.ts +0 -1
  142. package/src/router/client/index.ts +14 -100
  143. package/src/router/context.ts +6 -7
  144. package/src/router/fileRouter.ts +2 -6
  145. package/src/router/fileRouterController.ts +39 -159
  146. package/src/router/globals.ts +0 -4
  147. package/src/router/head.ts +7 -5
  148. package/src/router/index.ts +1 -12
  149. package/src/router/link.ts +3 -3
  150. package/src/router/{ssg → server}/index.ts +10 -17
  151. package/src/router/types.internal.ts +0 -5
  152. package/src/router/types.ts +4 -48
  153. package/src/router/utils/index.ts +16 -79
  154. package/src/scheduler.ts +83 -70
  155. package/src/signals/base.ts +0 -8
  156. package/src/signals/computed.ts +30 -18
  157. package/src/signals/for.ts +15 -10
  158. package/src/signals/utils.ts +2 -1
  159. package/src/signals/watch.ts +27 -22
  160. package/src/ssr/client.ts +1 -4
  161. package/src/ssr/server.ts +21 -20
  162. package/src/types.dom.ts +4 -5
  163. package/src/types.ts +0 -10
  164. package/src/utils/format.ts +0 -5
  165. package/src/utils/runtime.ts +6 -2
  166. package/src/utils/vdom.ts +2 -7
  167. package/dist/router/guard.d.ts +0 -17
  168. package/dist/router/guard.d.ts.map +0 -1
  169. package/dist/router/guard.js +0 -45
  170. package/dist/router/guard.js.map +0 -1
  171. package/dist/router/ssg/index.d.ts.map +0 -1
  172. package/dist/router/ssg/index.js.map +0 -1
  173. package/dist/router/ssr/index.d.ts +0 -20
  174. package/dist/router/ssr/index.d.ts.map +0 -1
  175. package/dist/router/ssr/index.js +0 -160
  176. package/dist/router/ssr/index.js.map +0 -1
  177. package/src/router/guard.ts +0 -72
  178. package/src/router/ssr/index.ts +0 -247
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/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,87 +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
6
  import {
6
- matchModules,
7
+ matchLayouts,
7
8
  matchRoute,
8
9
  match404Route,
9
10
  parseQuery,
10
- runBeforeEachGuards,
11
- runAfterEachGuards,
12
- runBeforeEnterHooks,
13
11
  } from "../utils/index.js"
14
- import type {
15
- FormattedViteImportMap,
16
- GuardModule,
17
- PageModule,
18
- } from "../types.internal"
12
+ import type { FormattedViteImportMap, PageModule } from "../types.internal"
19
13
  import type { FileRouterConfig, FileRouterPreloadConfig } from "../types"
20
- import {
21
- fileRouterInstance,
22
- fileRouterRoute,
23
- requestContext,
24
- routerCache,
25
- } from "../globals.js"
14
+ import { fileRouterInstance, fileRouterRoute, routerCache } from "../globals.js"
26
15
  import { FileRouterController } from "../fileRouterController.js"
27
16
  import { FileRouterDataLoadError } from "../errors.js"
28
17
  import { __DEV__ } from "../../env.js"
29
18
  import { RouterCache } from "../cache.js"
30
- import { RequestContext } from "../context.js"
31
19
 
32
20
  interface InitClientOptions {
33
21
  dir: string
34
22
  baseUrl: string
35
- pages: FormattedViteImportMap<PageModule>
23
+ pages: FormattedViteImportMap
36
24
  layouts: FormattedViteImportMap
37
- guards?: FormattedViteImportMap<GuardModule>
38
25
  transition: boolean
39
- hydrationMode?: Kiru.HydrationMode
40
26
  }
41
27
 
42
28
  export async function initClient(options: InitClientOptions) {
43
29
  routerCache.current = new RouterCache()
44
- const {
45
- dir,
46
- baseUrl,
47
- pages,
48
- layouts,
49
- guards,
50
- transition,
51
- hydrationMode = "static",
52
- } = options
53
-
54
- try {
55
- requestContext.current = JSON.parse(
56
- document.querySelector("[k-request-context]")!.innerHTML
57
- )
58
- } catch {}
30
+ const { dir, baseUrl, pages, layouts, transition } = options
59
31
 
60
- const preloaded = await preparePreloadConfig(
61
- options,
62
- false,
63
- hydrationMode === "dynamic"
64
- )
65
32
  const config: FileRouterConfig = {
66
33
  dir,
67
34
  baseUrl,
68
35
  pages,
69
36
  layouts,
70
- guards,
71
37
  transition,
72
- preloaded,
38
+ preloaded: await preparePreloadConfig(options),
73
39
  }
74
40
 
75
- const children = createElement(FileRouter, { config })
76
- const app =
77
- hydrationMode === "static"
78
- ? children
79
- : createElement(RequestContext.Provider, {
80
- value: requestContext.current,
81
- children,
82
- })
83
-
84
- hydrate(app, document.body, { hydrationMode })
41
+ const app = createElement(FileRouter, { config })
42
+ hydrate(app, document.body, { hydrationMode: "static" })
85
43
 
86
44
  if (__DEV__) {
87
45
  onLoadedDev()
@@ -90,8 +48,7 @@ export async function initClient(options: InitClientOptions) {
90
48
 
91
49
  async function preparePreloadConfig(
92
50
  options: InitClientOptions,
93
- isStatic404 = false,
94
- _isSSR = false
51
+ isStatic404 = false
95
52
  ): Promise<FileRouterPreloadConfig> {
96
53
  let pageProps = {}
97
54
  let cacheData: null | { value: unknown } = null
@@ -111,25 +68,7 @@ async function preparePreloadConfig(
111
68
  throw new Error(`No route defined (path: ${url.pathname}).`)
112
69
  }
113
70
 
114
- const layoutEntries = matchModules(options.layouts, routeMatch.routeSegments)
115
-
116
- // Load and run guards before loading page
117
- // if SSR, do we even need to do this?
118
- let guardModules: GuardModule[] = []
119
- if (options.guards) {
120
- const guardEntries = matchModules(options.guards, routeMatch.routeSegments)
121
- guardModules = await Promise.all(guardEntries.map((entry) => entry.load()))
122
-
123
- const redirectPath = await runBeforeEachGuards(
124
- guardModules,
125
- { ...requestContext.current },
126
- url.pathname
127
- )
128
- if (redirectPath !== null) {
129
- window.location.href = redirectPath
130
- }
131
- }
132
-
71
+ const layoutEntries = matchLayouts(options.layouts, routeMatch.routeSegments)
133
72
  fileRouterInstance.current = new FileRouterController()
134
73
  fileRouterRoute.current = routeMatch.route
135
74
  const [page, ...layouts] = await Promise.all([
@@ -138,22 +77,6 @@ async function preparePreloadConfig(
138
77
  ])
139
78
  fileRouterRoute.current = null
140
79
 
141
- const onBeforeEnter = page.config?.hooks?.onBeforeEnter
142
- if (onBeforeEnter) {
143
- const redirectPath = await runBeforeEnterHooks(
144
- toArray(onBeforeEnter),
145
- { ...requestContext.current },
146
- url.pathname
147
- )
148
- if (redirectPath) {
149
- window.location.href = redirectPath
150
- // @ts-ignore
151
- return
152
- }
153
- }
154
-
155
- const query = parseQuery(window.location.search)
156
-
157
80
  // Check if page has static props pre-loaded at build time
158
81
  if (page.__KIRU_STATIC_PROPS__) {
159
82
  const staticProps = page.__KIRU_STATIC_PROPS__[window.location.pathname]
@@ -177,30 +100,21 @@ async function preparePreloadConfig(
177
100
  const cacheKey = {
178
101
  path: window.location.pathname,
179
102
  params: routeMatch.params,
180
- query,
103
+ query: parseQuery(url.search),
181
104
  }
182
105
 
183
106
  cacheData = routerCache.current!.get(cacheKey, loader.cache)
184
107
  }
185
108
  }
186
109
 
187
- window.__kiru.on("mount", () => {
188
- runAfterEachGuards(
189
- guardModules,
190
- { ...requestContext.current },
191
- url.pathname
192
- )
193
- })
194
-
195
110
  return {
196
111
  pages: options.pages,
197
112
  layouts: options.layouts,
198
- guards: options.guards,
199
113
  page: page,
200
114
  pageProps: pageProps,
201
115
  pageLayouts: layouts,
202
116
  params: routeMatch.params,
203
- query: query,
117
+ query: parseQuery(url.search),
204
118
  route: routeMatch.route,
205
119
  cacheData,
206
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
  })