kiru 0.49.2 → 0.50.0-preview.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 (143) hide show
  1. package/dist/components/errorBoundary.d.ts +7 -0
  2. package/dist/components/errorBoundary.d.ts.map +1 -0
  3. package/dist/components/errorBoundary.js +6 -0
  4. package/dist/components/errorBoundary.js.map +1 -0
  5. package/dist/components/index.d.ts +2 -0
  6. package/dist/components/index.d.ts.map +1 -1
  7. package/dist/components/index.js +2 -0
  8. package/dist/components/index.js.map +1 -1
  9. package/dist/components/lazy.d.ts.map +1 -1
  10. package/dist/components/lazy.js +11 -136
  11. package/dist/components/lazy.js.map +1 -1
  12. package/dist/components/suspense.d.ts +34 -0
  13. package/dist/components/suspense.d.ts.map +1 -0
  14. package/dist/components/suspense.js +110 -0
  15. package/dist/components/suspense.js.map +1 -0
  16. package/dist/constants.d.ts +4 -2
  17. package/dist/constants.d.ts.map +1 -1
  18. package/dist/constants.js +4 -2
  19. package/dist/constants.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 +7 -0
  23. package/dist/hmr.js.map +1 -1
  24. package/dist/index.d.ts +1 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +1 -0
  27. package/dist/index.js.map +1 -1
  28. package/dist/recursiveRender.d.ts +6 -0
  29. package/dist/recursiveRender.d.ts.map +1 -0
  30. package/dist/recursiveRender.js +109 -0
  31. package/dist/recursiveRender.js.map +1 -0
  32. package/dist/renderToString.d.ts.map +1 -1
  33. package/dist/renderToString.js +10 -59
  34. package/dist/renderToString.js.map +1 -1
  35. package/dist/router/config.d.ts +3 -0
  36. package/dist/router/config.d.ts.map +1 -0
  37. package/dist/router/config.js +13 -0
  38. package/dist/router/config.js.map +1 -0
  39. package/dist/router/context.d.ts +15 -0
  40. package/dist/router/context.d.ts.map +1 -0
  41. package/dist/router/context.js +11 -0
  42. package/dist/router/context.js.map +1 -0
  43. package/dist/router/errors.d.ts +4 -0
  44. package/dist/router/errors.d.ts.map +1 -0
  45. package/dist/router/errors.js +7 -0
  46. package/dist/router/errors.js.map +1 -0
  47. package/dist/router/fileRouter.d.ts +48 -0
  48. package/dist/router/fileRouter.d.ts.map +1 -0
  49. package/dist/router/fileRouter.js +311 -0
  50. package/dist/router/fileRouter.js.map +1 -0
  51. package/dist/router/globals.d.ts +5 -0
  52. package/dist/router/globals.d.ts.map +1 -0
  53. package/dist/router/globals.js +4 -0
  54. package/dist/router/globals.js.map +1 -0
  55. package/dist/router/index.d.ts +7 -0
  56. package/dist/router/index.d.ts.map +1 -0
  57. package/dist/router/index.js +7 -0
  58. package/dist/router/index.js.map +1 -0
  59. package/dist/router/link.d.ts +8 -0
  60. package/dist/router/link.d.ts.map +1 -0
  61. package/dist/router/link.js +15 -0
  62. package/dist/router/link.js.map +1 -0
  63. package/dist/router/types.d.ts +63 -0
  64. package/dist/router/types.d.ts.map +1 -0
  65. package/dist/router/types.internal.d.ts +12 -0
  66. package/dist/router/types.internal.d.ts.map +1 -0
  67. package/dist/router/types.internal.js +2 -0
  68. package/dist/router/types.internal.js.map +1 -0
  69. package/dist/router/types.js +2 -0
  70. package/dist/router/types.js.map +1 -0
  71. package/dist/scheduler.d.ts.map +1 -1
  72. package/dist/scheduler.js +35 -10
  73. package/dist/scheduler.js.map +1 -1
  74. package/dist/ssr/server.d.ts +4 -1
  75. package/dist/ssr/server.d.ts.map +1 -1
  76. package/dist/ssr/server.js +50 -82
  77. package/dist/ssr/server.js.map +1 -1
  78. package/dist/types.d.ts +10 -2
  79. package/dist/types.d.ts.map +1 -1
  80. package/dist/types.utils.d.ts +6 -7
  81. package/dist/types.utils.d.ts.map +1 -1
  82. package/dist/utils/runtime.d.ts +1 -1
  83. package/dist/utils/runtime.d.ts.map +1 -1
  84. package/dist/utils/runtime.js.map +1 -1
  85. package/dist/utils/vdom.d.ts +3 -1
  86. package/dist/utils/vdom.d.ts.map +1 -1
  87. package/dist/utils/vdom.js +6 -5
  88. package/dist/utils/vdom.js.map +1 -1
  89. package/package.json +4 -8
  90. package/src/components/errorBoundary.ts +16 -0
  91. package/src/components/index.ts +2 -0
  92. package/src/components/lazy.ts +12 -169
  93. package/src/components/suspense.ts +191 -0
  94. package/src/constants.ts +6 -2
  95. package/src/hmr.ts +8 -0
  96. package/src/index.ts +1 -0
  97. package/src/recursiveRender.ts +127 -0
  98. package/src/renderToString.ts +10 -73
  99. package/src/router/config.ts +15 -0
  100. package/src/router/context.ts +23 -0
  101. package/src/router/errors.ts +6 -0
  102. package/src/router/fileRouter.ts +475 -0
  103. package/src/router/globals.ts +5 -0
  104. package/src/router/index.ts +6 -0
  105. package/src/router/link.ts +32 -0
  106. package/src/router/types.internal.ts +14 -0
  107. package/src/router/types.ts +81 -0
  108. package/src/scheduler.ts +45 -12
  109. package/src/ssr/server.ts +58 -95
  110. package/src/types.ts +11 -2
  111. package/src/types.utils.ts +6 -11
  112. package/src/utils/runtime.ts +1 -1
  113. package/src/utils/vdom.ts +11 -4
  114. package/dist/components/router/index.d.ts +0 -3
  115. package/dist/components/router/index.d.ts.map +0 -1
  116. package/dist/components/router/index.js +0 -3
  117. package/dist/components/router/index.js.map +0 -1
  118. package/dist/components/router/route.d.ts +0 -46
  119. package/dist/components/router/route.d.ts.map +0 -1
  120. package/dist/components/router/route.js +0 -8
  121. package/dist/components/router/route.js.map +0 -1
  122. package/dist/components/router/router.d.ts +0 -62
  123. package/dist/components/router/router.d.ts.map +0 -1
  124. package/dist/components/router/router.js +0 -181
  125. package/dist/components/router/router.js.map +0 -1
  126. package/dist/components/router/routerUtils.d.ts +0 -5
  127. package/dist/components/router/routerUtils.d.ts.map +0 -1
  128. package/dist/components/router/routerUtils.js +0 -39
  129. package/dist/components/router/routerUtils.js.map +0 -1
  130. package/dist/ssr/hydrationBoundary.d.ts +0 -27
  131. package/dist/ssr/hydrationBoundary.d.ts.map +0 -1
  132. package/dist/ssr/hydrationBoundary.js +0 -30
  133. package/dist/ssr/hydrationBoundary.js.map +0 -1
  134. package/dist/ssr/index.d.ts +0 -2
  135. package/dist/ssr/index.d.ts.map +0 -1
  136. package/dist/ssr/index.js +0 -2
  137. package/dist/ssr/index.js.map +0 -1
  138. package/src/components/router/index.ts +0 -2
  139. package/src/components/router/route.ts +0 -51
  140. package/src/components/router/router.ts +0 -280
  141. package/src/components/router/routerUtils.ts +0 -49
  142. package/src/ssr/hydrationBoundary.ts +0 -63
  143. package/src/ssr/index.ts +0 -1
@@ -0,0 +1,127 @@
1
+ import { node, hookIndex } from "./globals.js"
2
+ import {
3
+ isVNode,
4
+ encodeHtmlEntities,
5
+ propsToElementAttributes,
6
+ isExoticType,
7
+ assertValidElementProps,
8
+ } from "./utils/index.js"
9
+ import { Signal } from "./signals/base.js"
10
+ import { $ERROR_BOUNDARY, voidElements, $SUSPENSE_THROW } from "./constants.js"
11
+ import { __DEV__ } from "./env.js"
12
+ import { isSuspenseThrowValue } from "./components/suspense.js"
13
+ import type { ErrorBoundaryNode } from "./types.utils"
14
+
15
+ export interface RecursiveRenderContext {
16
+ write(chunk: string): void
17
+ onPending?: (data: Kiru.StatefulPromise<unknown>[]) => void
18
+ }
19
+
20
+ export function recursiveRender(
21
+ ctx: RecursiveRenderContext,
22
+ el: unknown,
23
+ parent: Kiru.VNode | null,
24
+ idx: number
25
+ ): void {
26
+ if (el === null) return
27
+ if (el === undefined) return
28
+ if (typeof el === "boolean") return
29
+ if (typeof el === "string") {
30
+ return ctx.write(encodeHtmlEntities(el))
31
+ }
32
+ if (typeof el === "number" || typeof el === "bigint") {
33
+ return ctx.write(el.toString())
34
+ }
35
+ if (el instanceof Array) {
36
+ return el.forEach((c, i) => recursiveRender(ctx, c, parent, i))
37
+ }
38
+ if (Signal.isSignal(el)) {
39
+ return ctx.write(String(el.peek()))
40
+ }
41
+ if (!isVNode(el)) {
42
+ return ctx.write(String(el))
43
+ }
44
+ el.parent = parent
45
+ el.depth = (parent?.depth ?? -1) + 1
46
+ el.index = idx
47
+ const { type, props = {} } = el
48
+ if (type === "#text") {
49
+ return ctx.write(encodeHtmlEntities(props.nodeValue ?? ""))
50
+ }
51
+
52
+ const children = props.children
53
+ if (isExoticType(type)) {
54
+ if (type === $ERROR_BOUNDARY) {
55
+ let boundaryBuffer = ""
56
+ const pending = new Set<Kiru.StatefulPromise<unknown>>()
57
+ const boundaryCtx: RecursiveRenderContext = {
58
+ write(chunk) {
59
+ boundaryBuffer += chunk
60
+ },
61
+ onPending(data) {
62
+ data.forEach((p) => pending.add(p))
63
+ },
64
+ }
65
+ try {
66
+ recursiveRender(boundaryCtx, children, el, idx)
67
+ // flush successful render
68
+ ctx.write(boundaryBuffer)
69
+ ctx.onPending?.([...pending])
70
+ } catch (error) {
71
+ if (isSuspenseThrowValue(error)) {
72
+ throw error
73
+ }
74
+ const e = error instanceof Error ? error : new Error(String(error))
75
+ const { fallback, onError } = props as ErrorBoundaryNode["props"]
76
+ onError?.(e)
77
+ const fallbackContent =
78
+ typeof fallback === "function" ? fallback(e) : fallback
79
+ recursiveRender(ctx, fallbackContent, el, 0)
80
+ }
81
+ return
82
+ }
83
+
84
+ recursiveRender(ctx, children, el, idx)
85
+ return
86
+ }
87
+
88
+ if (typeof type !== "string") {
89
+ try {
90
+ hookIndex.current = 0
91
+ node.current = el
92
+ const res = type(props)
93
+ recursiveRender(ctx, res, el, idx)
94
+ return
95
+ } catch (error) {
96
+ if (isSuspenseThrowValue(error)) {
97
+ const { fallback, pending } = error[$SUSPENSE_THROW]
98
+ ctx.onPending?.(pending)
99
+ return recursiveRender(ctx, fallback, el, 0)
100
+ }
101
+ throw error
102
+ } finally {
103
+ node.current = null
104
+ }
105
+ }
106
+
107
+ if (__DEV__) assertValidElementProps(el)
108
+ const attrs = propsToElementAttributes(props)
109
+ ctx.write(`<${type}${attrs.length ? ` ${attrs}` : ""}>`)
110
+
111
+ if (voidElements.has(type)) return
112
+
113
+ if ("innerHTML" in props) {
114
+ ctx.write(
115
+ String(
116
+ Signal.isSignal(props.innerHTML)
117
+ ? props.innerHTML.peek()
118
+ : props.innerHTML
119
+ )
120
+ )
121
+ } else if (Array.isArray(children)) {
122
+ children.forEach((c, i) => recursiveRender(ctx, c, el, i))
123
+ } else {
124
+ recursiveRender(ctx, children, el, 0)
125
+ }
126
+ ctx.write(`</${type}>`)
127
+ }
@@ -1,81 +1,18 @@
1
- import { node, renderMode } from "./globals.js"
1
+ import { renderMode } from "./globals.js"
2
2
  import { Fragment } from "./element.js"
3
- import {
4
- isVNode,
5
- encodeHtmlEntities,
6
- propsToElementAttributes,
7
- isExoticType,
8
- assertValidElementProps,
9
- } from "./utils/index.js"
10
- import { Signal } from "./signals/base.js"
11
- import { $HYDRATION_BOUNDARY, voidElements } from "./constants.js"
12
- import { HYDRATION_BOUNDARY_MARKER } from "./ssr/hydrationBoundary.js"
13
3
  import { __DEV__ } from "./env.js"
4
+ import { recursiveRender, RecursiveRenderContext } from "./recursiveRender.js"
14
5
 
15
6
  export function renderToString(element: JSX.Element) {
16
7
  const prev = renderMode.current
17
8
  renderMode.current = "string"
18
- const rootNode = Fragment({ children: element })
19
- const res = renderToString_internal(rootNode, null, 0)
20
- renderMode.current = prev
21
- return res
22
- }
23
-
24
- function renderToString_internal(
25
- el: unknown,
26
- parent: Kiru.VNode | null,
27
- idx: number
28
- ): string {
29
- if (el === null) return ""
30
- if (el === undefined) return ""
31
- if (typeof el === "boolean") return ""
32
- if (typeof el === "string") return encodeHtmlEntities(el)
33
- if (typeof el === "number" || typeof el === "bigint") return el.toString()
34
- if (el instanceof Array) {
35
- return el.map((c, i) => renderToString_internal(c, parent, i)).join("")
36
- }
37
- if (Signal.isSignal(el)) return String(el.peek())
38
- if (!isVNode(el)) return String(el)
39
- el.parent = parent
40
- el.depth = (parent?.depth ?? -1) + 1
41
- el.index = idx
42
- const { type, props = {} } = el
43
- if (type === "#text") return encodeHtmlEntities(props.nodeValue ?? "")
44
-
45
- const children = props.children
46
- if (isExoticType(type)) {
47
- if (type === $HYDRATION_BOUNDARY) {
48
- return `<!--${HYDRATION_BOUNDARY_MARKER}-->${renderToString_internal(
49
- children,
50
- el,
51
- idx
52
- )}<!--/${HYDRATION_BOUNDARY_MARKER}-->`
53
- }
54
-
55
- return renderToString_internal(children, el, idx)
9
+ let result = ""
10
+ const ctx: RecursiveRenderContext = {
11
+ write(chunk) {
12
+ result += chunk
13
+ },
56
14
  }
57
-
58
- if (typeof type !== "string") {
59
- node.current = el
60
- const res = type(props)
61
- node.current = null
62
- return renderToString_internal(res, el, idx)
63
- }
64
-
65
- if (__DEV__) {
66
- assertValidElementProps(el)
67
- }
68
- const attrs = propsToElementAttributes(props)
69
- const inner =
70
- "innerHTML" in props
71
- ? Signal.isSignal(props.innerHTML)
72
- ? props.innerHTML.peek()
73
- : props.innerHTML
74
- : Array.isArray(children)
75
- ? children.map((c, i) => renderToString_internal(c, el, i)).join("")
76
- : renderToString_internal(children, el, 0)
77
-
78
- return `<${type}${attrs.length ? ` ${attrs}` : ""}>${
79
- voidElements.has(type) ? "" : `${inner}</${type}>`
80
- }`
15
+ recursiveRender(ctx, Fragment({ children: element }), null, 0)
16
+ renderMode.current = prev
17
+ return result
81
18
  }
@@ -0,0 +1,15 @@
1
+ import { __DEV__ } from "../env.js"
2
+ import { fileRouterInstance } from "./globals.js"
3
+ import type { PageConfig } from "./types"
4
+
5
+ export function definePageConfig<T extends PageConfig>(config: T): T {
6
+ if (__DEV__) {
7
+ const filePath = window.__kiru?.HMRContext?.getCurrentFilePath()
8
+ const fileRouter = fileRouterInstance.current
9
+ if (filePath && fileRouter) {
10
+ fileRouter.onPageConfigDefined(filePath, config)
11
+ }
12
+ }
13
+
14
+ return config
15
+ }
@@ -0,0 +1,23 @@
1
+ import { createContext } from "../context.js"
2
+ import { __DEV__ } from "../env.js"
3
+ import { useContext } from "../hooks/index.js"
4
+ import type { RouteQuery, RouterState } from "./types.js"
5
+
6
+ export interface FileRouterContextType {
7
+ state: RouterState
8
+ navigate: (
9
+ path: string,
10
+ options?: { replace?: boolean; transition?: boolean }
11
+ ) => Promise<void>
12
+ reload: (options?: { transition?: boolean }) => Promise<void>
13
+ setQuery: (query: RouteQuery) => void
14
+ }
15
+
16
+ export const RouterContext = createContext<FileRouterContextType>(null!)
17
+ if (__DEV__) {
18
+ RouterContext.displayName = "RouterContext"
19
+ }
20
+
21
+ export function useFileRouter(): FileRouterContextType {
22
+ return useContext(RouterContext)
23
+ }
@@ -0,0 +1,6 @@
1
+ export class FileRouterDataLoadError extends Error {
2
+ constructor(cause: unknown) {
3
+ super("An error occurred while loading route data")
4
+ this.cause = cause
5
+ }
6
+ }