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.
- package/dist/components/errorBoundary.d.ts +7 -0
- package/dist/components/errorBoundary.d.ts.map +1 -0
- package/dist/components/errorBoundary.js +6 -0
- package/dist/components/errorBoundary.js.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +2 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/lazy.d.ts.map +1 -1
- package/dist/components/lazy.js +11 -136
- package/dist/components/lazy.js.map +1 -1
- package/dist/components/suspense.d.ts +34 -0
- package/dist/components/suspense.d.ts.map +1 -0
- package/dist/components/suspense.js +110 -0
- package/dist/components/suspense.js.map +1 -0
- package/dist/constants.d.ts +4 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +4 -2
- package/dist/constants.js.map +1 -1
- package/dist/hmr.d.ts +1 -0
- package/dist/hmr.d.ts.map +1 -1
- package/dist/hmr.js +7 -0
- package/dist/hmr.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/recursiveRender.d.ts +6 -0
- package/dist/recursiveRender.d.ts.map +1 -0
- package/dist/recursiveRender.js +109 -0
- package/dist/recursiveRender.js.map +1 -0
- package/dist/renderToString.d.ts.map +1 -1
- package/dist/renderToString.js +10 -59
- package/dist/renderToString.js.map +1 -1
- package/dist/router/config.d.ts +3 -0
- package/dist/router/config.d.ts.map +1 -0
- package/dist/router/config.js +13 -0
- package/dist/router/config.js.map +1 -0
- package/dist/router/context.d.ts +15 -0
- package/dist/router/context.d.ts.map +1 -0
- package/dist/router/context.js +11 -0
- package/dist/router/context.js.map +1 -0
- package/dist/router/errors.d.ts +4 -0
- package/dist/router/errors.d.ts.map +1 -0
- package/dist/router/errors.js +7 -0
- package/dist/router/errors.js.map +1 -0
- package/dist/router/fileRouter.d.ts +48 -0
- package/dist/router/fileRouter.d.ts.map +1 -0
- package/dist/router/fileRouter.js +311 -0
- package/dist/router/fileRouter.js.map +1 -0
- package/dist/router/globals.d.ts +5 -0
- package/dist/router/globals.d.ts.map +1 -0
- package/dist/router/globals.js +4 -0
- package/dist/router/globals.js.map +1 -0
- package/dist/router/index.d.ts +7 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +7 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/link.d.ts +8 -0
- package/dist/router/link.d.ts.map +1 -0
- package/dist/router/link.js +15 -0
- package/dist/router/link.js.map +1 -0
- package/dist/router/types.d.ts +63 -0
- package/dist/router/types.d.ts.map +1 -0
- package/dist/router/types.internal.d.ts +12 -0
- package/dist/router/types.internal.d.ts.map +1 -0
- package/dist/router/types.internal.js +2 -0
- package/dist/router/types.internal.js.map +1 -0
- package/dist/router/types.js +2 -0
- package/dist/router/types.js.map +1 -0
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +35 -10
- package/dist/scheduler.js.map +1 -1
- package/dist/ssr/server.d.ts +4 -1
- package/dist/ssr/server.d.ts.map +1 -1
- package/dist/ssr/server.js +50 -82
- package/dist/ssr/server.js.map +1 -1
- package/dist/types.d.ts +10 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.utils.d.ts +6 -7
- package/dist/types.utils.d.ts.map +1 -1
- package/dist/utils/runtime.d.ts +1 -1
- package/dist/utils/runtime.d.ts.map +1 -1
- package/dist/utils/runtime.js.map +1 -1
- package/dist/utils/vdom.d.ts +3 -1
- package/dist/utils/vdom.d.ts.map +1 -1
- package/dist/utils/vdom.js +6 -5
- package/dist/utils/vdom.js.map +1 -1
- package/package.json +4 -8
- package/src/components/errorBoundary.ts +16 -0
- package/src/components/index.ts +2 -0
- package/src/components/lazy.ts +12 -169
- package/src/components/suspense.ts +191 -0
- package/src/constants.ts +6 -2
- package/src/hmr.ts +8 -0
- package/src/index.ts +1 -0
- package/src/recursiveRender.ts +127 -0
- package/src/renderToString.ts +10 -73
- package/src/router/config.ts +15 -0
- package/src/router/context.ts +23 -0
- package/src/router/errors.ts +6 -0
- package/src/router/fileRouter.ts +475 -0
- package/src/router/globals.ts +5 -0
- package/src/router/index.ts +6 -0
- package/src/router/link.ts +32 -0
- package/src/router/types.internal.ts +14 -0
- package/src/router/types.ts +81 -0
- package/src/scheduler.ts +45 -12
- package/src/ssr/server.ts +58 -95
- package/src/types.ts +11 -2
- package/src/types.utils.ts +6 -11
- package/src/utils/runtime.ts +1 -1
- package/src/utils/vdom.ts +11 -4
- package/dist/components/router/index.d.ts +0 -3
- package/dist/components/router/index.d.ts.map +0 -1
- package/dist/components/router/index.js +0 -3
- package/dist/components/router/index.js.map +0 -1
- package/dist/components/router/route.d.ts +0 -46
- package/dist/components/router/route.d.ts.map +0 -1
- package/dist/components/router/route.js +0 -8
- package/dist/components/router/route.js.map +0 -1
- package/dist/components/router/router.d.ts +0 -62
- package/dist/components/router/router.d.ts.map +0 -1
- package/dist/components/router/router.js +0 -181
- package/dist/components/router/router.js.map +0 -1
- package/dist/components/router/routerUtils.d.ts +0 -5
- package/dist/components/router/routerUtils.d.ts.map +0 -1
- package/dist/components/router/routerUtils.js +0 -39
- package/dist/components/router/routerUtils.js.map +0 -1
- package/dist/ssr/hydrationBoundary.d.ts +0 -27
- package/dist/ssr/hydrationBoundary.d.ts.map +0 -1
- package/dist/ssr/hydrationBoundary.js +0 -30
- package/dist/ssr/hydrationBoundary.js.map +0 -1
- package/dist/ssr/index.d.ts +0 -2
- package/dist/ssr/index.d.ts.map +0 -1
- package/dist/ssr/index.js +0 -2
- package/dist/ssr/index.js.map +0 -1
- package/src/components/router/index.ts +0 -2
- package/src/components/router/route.ts +0 -51
- package/src/components/router/router.ts +0 -280
- package/src/components/router/routerUtils.ts +0 -49
- package/src/ssr/hydrationBoundary.ts +0 -63
- 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
|
+
}
|
package/src/renderToString.ts
CHANGED
|
@@ -1,81 +1,18 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
59
|
-
|
|
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
|
+
}
|