kiru 0.46.1 → 0.47.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/appContext.d.ts +6 -17
- package/dist/appContext.d.ts.map +1 -1
- package/dist/appContext.js +39 -95
- package/dist/appContext.js.map +1 -1
- package/dist/constants.d.ts +3 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -1
- package/dist/constants.js.map +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +0 -2
- package/dist/context.js.map +1 -1
- package/dist/dom.d.ts.map +1 -1
- package/dist/dom.js +12 -14
- package/dist/dom.js.map +1 -1
- package/dist/element.js +2 -2
- package/dist/element.js.map +1 -1
- package/dist/hmr.d.ts +3 -3
- package/dist/hmr.d.ts.map +1 -1
- package/dist/hmr.js +0 -2
- package/dist/hmr.js.map +1 -1
- package/dist/index.d.ts +1 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -21
- package/dist/index.js.map +1 -1
- package/dist/memo.d.ts.map +1 -1
- package/dist/memo.js +1 -3
- package/dist/memo.js.map +1 -1
- package/dist/portal.d.ts +2 -5
- package/dist/portal.d.ts.map +1 -1
- package/dist/portal.js +22 -22
- package/dist/portal.js.map +1 -1
- package/dist/profiling.d.ts +1 -1
- package/dist/props.js +1 -1
- package/dist/props.js.map +1 -1
- package/dist/reconciler.d.ts.map +1 -1
- package/dist/reconciler.js +3 -3
- package/dist/reconciler.js.map +1 -1
- package/dist/renderToString.d.ts +1 -1
- package/dist/renderToString.d.ts.map +1 -1
- package/dist/renderToString.js +4 -7
- package/dist/renderToString.js.map +1 -1
- package/dist/scheduler.d.ts +3 -3
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +55 -71
- package/dist/scheduler.js.map +1 -1
- package/dist/signals/base.d.ts +1 -1
- package/dist/signals/base.d.ts.map +1 -1
- package/dist/signals/base.js +2 -2
- package/dist/signals/base.js.map +1 -1
- package/dist/signals/computed.d.ts +1 -1
- package/dist/signals/computed.d.ts.map +1 -1
- package/dist/signals/computed.js +3 -3
- package/dist/signals/computed.js.map +1 -1
- package/dist/signals/effect.d.ts +1 -1
- package/dist/signals/effect.d.ts.map +1 -1
- package/dist/signals/effect.js +3 -2
- package/dist/signals/effect.js.map +1 -1
- package/dist/signals/globals.d.ts +1 -1
- package/dist/signals/globals.d.ts.map +1 -1
- package/dist/signals/jsx.d.ts +1 -1
- package/dist/signals/jsx.d.ts.map +1 -1
- package/dist/signals/types.d.ts +1 -1
- package/dist/signals/types.d.ts.map +1 -1
- package/dist/signals/utils.d.ts +1 -1
- package/dist/signals/utils.d.ts.map +1 -1
- package/dist/signals/utils.js +1 -1
- package/dist/signals/utils.js.map +1 -1
- package/dist/ssr/client.d.ts +1 -2
- package/dist/ssr/client.d.ts.map +1 -1
- package/dist/ssr/client.js +6 -4
- package/dist/ssr/client.js.map +1 -1
- package/dist/ssr/server.d.ts +1 -1
- package/dist/ssr/server.d.ts.map +1 -1
- package/dist/ssr/server.js +23 -26
- package/dist/ssr/server.js.map +1 -1
- package/dist/types.d.ts +0 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +4 -2
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/appContext.ts +50 -117
- package/src/constants.ts +4 -0
- package/src/context.ts +0 -1
- package/src/dom.ts +12 -11
- package/src/element.ts +2 -2
- package/src/hmr.ts +4 -5
- package/src/index.ts +1 -41
- package/src/memo.ts +1 -3
- package/src/portal.ts +22 -26
- package/src/props.ts +1 -1
- package/src/reconciler.ts +3 -2
- package/src/renderToString.ts +4 -10
- package/src/scheduler.ts +54 -72
- package/src/signals/base.ts +4 -4
- package/src/signals/computed.ts +4 -4
- package/src/signals/effect.ts +4 -3
- package/src/signals/globals.ts +1 -1
- package/src/signals/jsx.ts +1 -1
- package/src/signals/types.ts +1 -1
- package/src/signals/utils.ts +1 -1
- package/src/ssr/client.ts +13 -19
- package/src/ssr/server.ts +24 -34
- package/src/types.ts +0 -1
- package/src/utils.ts +3 -1
package/src/appContext.ts
CHANGED
|
@@ -1,140 +1,73 @@
|
|
|
1
|
+
import { FLAG_STATIC_DOM } from "./constants.js"
|
|
1
2
|
import { createElement } from "./element.js"
|
|
2
3
|
import { __DEV__ } from "./env.js"
|
|
3
|
-
import {
|
|
4
|
-
import { renderMode } from "./globals.js"
|
|
5
|
-
import { hydrationStack } from "./hydration.js"
|
|
6
|
-
import {
|
|
7
|
-
requestDelete,
|
|
8
|
-
requestUpdate,
|
|
9
|
-
flushSync,
|
|
10
|
-
nextIdle,
|
|
11
|
-
} from "./scheduler.js"
|
|
12
|
-
import { generateRandomID } from "./generateId.js"
|
|
4
|
+
import { requestUpdate, flushSync } from "./scheduler.js"
|
|
13
5
|
|
|
14
6
|
type VNode = Kiru.VNode
|
|
15
7
|
|
|
16
8
|
export interface AppContextOptions {
|
|
17
|
-
root?: HTMLElement
|
|
18
|
-
/**
|
|
19
|
-
* @internal
|
|
20
|
-
* Sets the root node type for the app. Used for SSR & rendering without the DOM.
|
|
21
|
-
*/
|
|
22
|
-
rootType?: ({ children }: { children: JSX.Children }) => JSX.Element
|
|
23
9
|
name?: string
|
|
24
10
|
}
|
|
25
11
|
|
|
26
|
-
export interface AppContext
|
|
27
|
-
id:
|
|
12
|
+
export interface AppContext {
|
|
13
|
+
id: number
|
|
28
14
|
name: string
|
|
29
|
-
rootNode
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
mount(): Promise<AppContext<T>>
|
|
33
|
-
unmount(): Promise<AppContext<T>>
|
|
34
|
-
setProps(fn: (oldProps: T) => T): Promise<AppContext<T>>
|
|
15
|
+
rootNode: VNode
|
|
16
|
+
render(children: JSX.Element): void
|
|
17
|
+
unmount(): void
|
|
35
18
|
}
|
|
36
19
|
|
|
37
|
-
|
|
38
|
-
appFunc: (props: T) => JSX.Element,
|
|
39
|
-
appProps = {} as T,
|
|
40
|
-
options?: AppContextOptions
|
|
41
|
-
): AppContext<T> {
|
|
42
|
-
const id = generateRandomID()
|
|
43
|
-
const name = options?.name ?? "App-" + id
|
|
44
|
-
let root = options?.root
|
|
45
|
-
let mounted = false
|
|
46
|
-
let appContext: AppContext<T>
|
|
20
|
+
let appId = 0
|
|
47
21
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
22
|
+
export function mount(
|
|
23
|
+
children: JSX.Element,
|
|
24
|
+
container: HTMLElement,
|
|
25
|
+
options?: AppContextOptions
|
|
26
|
+
): AppContext {
|
|
27
|
+
const rootNode = createElement(container.nodeName.toLowerCase(), {})
|
|
28
|
+
if (__DEV__) {
|
|
29
|
+
if (container.__kiruNode) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
"[kiru]: container in use - call unmount on the previous app first."
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
container.__kiruNode = rootNode
|
|
57
35
|
}
|
|
36
|
+
rootNode.dom = container
|
|
37
|
+
rootNode.flags |= FLAG_STATIC_DOM
|
|
58
38
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (__DEV__) {
|
|
68
|
-
root.__kiruNode = rootNode
|
|
69
|
-
}
|
|
70
|
-
if (renderMode.current === "hydrate") {
|
|
71
|
-
hydrationStack.captureEvents(root!)
|
|
72
|
-
}
|
|
73
|
-
nextIdle(() => {
|
|
74
|
-
if (renderMode.current === "hydrate") {
|
|
75
|
-
hydrationStack.releaseEvents(root!)
|
|
76
|
-
}
|
|
77
|
-
mounted = true
|
|
78
|
-
if (__DEV__) {
|
|
79
|
-
window.__kiru?.emit("mount", appContext)
|
|
80
|
-
}
|
|
81
|
-
resolve(appContext)
|
|
82
|
-
}, false)
|
|
83
|
-
requestUpdate(rootNode)
|
|
84
|
-
flushSync()
|
|
85
|
-
})
|
|
39
|
+
const id = appId++
|
|
40
|
+
const name = options?.name ?? `App-${id}`
|
|
41
|
+
const appContext: AppContext = {
|
|
42
|
+
id,
|
|
43
|
+
name,
|
|
44
|
+
rootNode,
|
|
45
|
+
render,
|
|
46
|
+
unmount,
|
|
86
47
|
}
|
|
87
48
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
requestDelete(rootNode.child)
|
|
49
|
+
if (__DEV__) {
|
|
50
|
+
rootNode.app = appContext
|
|
51
|
+
window.__kiru?.emit("mount", appContext)
|
|
52
|
+
}
|
|
93
53
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
window.__kiru?.emit("unmount", appContext)
|
|
99
|
-
}
|
|
100
|
-
resolve(appContext)
|
|
101
|
-
})
|
|
102
|
-
})
|
|
54
|
+
function render(children: JSX.Element) {
|
|
55
|
+
rootNode.props.children = children
|
|
56
|
+
requestUpdate(rootNode)
|
|
57
|
+
flushSync()
|
|
103
58
|
}
|
|
104
59
|
|
|
105
|
-
function
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
...Object.assign(rest, fn(rest as T)),
|
|
115
|
-
children,
|
|
116
|
-
ref,
|
|
117
|
-
key,
|
|
118
|
-
}
|
|
119
|
-
requestUpdate(rootChild)
|
|
120
|
-
nextIdle(() => resolve(appContext))
|
|
121
|
-
})
|
|
60
|
+
function unmount() {
|
|
61
|
+
rootNode.props.children = null
|
|
62
|
+
requestUpdate(rootNode)
|
|
63
|
+
flushSync()
|
|
64
|
+
if (__DEV__) {
|
|
65
|
+
delete container.__kiruNode
|
|
66
|
+
delete rootNode.app
|
|
67
|
+
window.__kiru?.emit("unmount", appContext)
|
|
68
|
+
}
|
|
122
69
|
}
|
|
123
70
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
name,
|
|
127
|
-
get rootNode() {
|
|
128
|
-
return rootNode
|
|
129
|
-
},
|
|
130
|
-
get root() {
|
|
131
|
-
return root
|
|
132
|
-
},
|
|
133
|
-
get mounted() {
|
|
134
|
-
return mounted
|
|
135
|
-
},
|
|
136
|
-
mount,
|
|
137
|
-
unmount,
|
|
138
|
-
setProps,
|
|
139
|
-
})
|
|
71
|
+
render(children)
|
|
72
|
+
return appContext
|
|
140
73
|
}
|
package/src/constants.ts
CHANGED
|
@@ -13,6 +13,8 @@ export {
|
|
|
13
13
|
FLAG_PLACEMENT,
|
|
14
14
|
FLAG_DELETION,
|
|
15
15
|
FLAG_HAS_MEMO_ANCESTOR,
|
|
16
|
+
FLAG_STATIC_DOM,
|
|
17
|
+
FLAG_MEMO,
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
export { voidElements, svgTags, booleanAttributes }
|
|
@@ -32,6 +34,8 @@ const FLAG_UPDATE = 1 << 1
|
|
|
32
34
|
const FLAG_PLACEMENT = 1 << 2
|
|
33
35
|
const FLAG_DELETION = 1 << 3
|
|
34
36
|
const FLAG_HAS_MEMO_ANCESTOR = 1 << 4
|
|
37
|
+
const FLAG_STATIC_DOM = 1 << 5
|
|
38
|
+
const FLAG_MEMO = 1 << 6
|
|
35
39
|
|
|
36
40
|
const REGEX_UNIT = {
|
|
37
41
|
AMP_G: /&/g,
|
package/src/context.ts
CHANGED
|
@@ -31,7 +31,6 @@ export function createContext<T>(defaultValue: T): Kiru.Context<T> {
|
|
|
31
31
|
inject: (prev) => {
|
|
32
32
|
const newProvider = ctx.Provider
|
|
33
33
|
window.__kiru!.apps.forEach((ctx) => {
|
|
34
|
-
if (!ctx.mounted || !ctx.rootNode) return
|
|
35
34
|
traverseApply(ctx.rootNode, (vNode) => {
|
|
36
35
|
if (vNode.type === prev.Provider) {
|
|
37
36
|
vNode.type = newProvider
|
package/src/dom.ts
CHANGED
|
@@ -11,13 +11,14 @@ import {
|
|
|
11
11
|
FLAG_DELETION,
|
|
12
12
|
FLAG_PLACEMENT,
|
|
13
13
|
FLAG_UPDATE,
|
|
14
|
+
FLAG_STATIC_DOM,
|
|
14
15
|
svgTags,
|
|
15
16
|
} from "./constants.js"
|
|
16
|
-
import { Signal
|
|
17
|
+
import { Signal } from "./signals/base.js"
|
|
18
|
+
import { unwrap } from "./signals/utils.js"
|
|
17
19
|
import { renderMode } from "./globals.js"
|
|
18
20
|
import { hydrationStack } from "./hydration.js"
|
|
19
21
|
import { StyleObject } from "./types.dom.js"
|
|
20
|
-
import { isPortal } from "./portal.js"
|
|
21
22
|
import { __DEV__ } from "./env.js"
|
|
22
23
|
import { KiruError } from "./error.js"
|
|
23
24
|
import type {
|
|
@@ -146,7 +147,6 @@ const vNodeToWrappedFocusEventHandlersMap = new WeakMap<
|
|
|
146
147
|
>()
|
|
147
148
|
|
|
148
149
|
function updateDom(vNode: VNode) {
|
|
149
|
-
if (isPortal(vNode)) return
|
|
150
150
|
const dom = vNode.dom as SomeDom
|
|
151
151
|
const prevProps: Record<string, any> = vNode.prev?.props ?? {}
|
|
152
152
|
const nextProps: Record<string, any> = vNode.props ?? {}
|
|
@@ -363,7 +363,7 @@ function hydrateDom(vNode: VNode) {
|
|
|
363
363
|
})
|
|
364
364
|
}
|
|
365
365
|
vNode.dom = dom
|
|
366
|
-
if (vNode.type !== "#text") {
|
|
366
|
+
if (vNode.type !== "#text" && !(vNode.flags & FLAG_STATIC_DOM)) {
|
|
367
367
|
updateDom(vNode)
|
|
368
368
|
return
|
|
369
369
|
}
|
|
@@ -571,8 +571,8 @@ function getNextSiblingDom(vNode: VNode, parent: ElementVNode): MaybeDom {
|
|
|
571
571
|
let sibling = node.sibling
|
|
572
572
|
|
|
573
573
|
while (sibling) {
|
|
574
|
-
// Skip unmounted, to-be-placed &
|
|
575
|
-
if (!(sibling.flags & FLAG_PLACEMENT
|
|
574
|
+
// Skip unmounted, to-be-placed & static nodes
|
|
575
|
+
if (!(sibling.flags & (FLAG_PLACEMENT | FLAG_STATIC_DOM))) {
|
|
576
576
|
// Descend into the child to find host dom
|
|
577
577
|
const dom = findFirstHostDom(sibling)
|
|
578
578
|
if (dom?.isConnected) return dom
|
|
@@ -582,7 +582,7 @@ function getNextSiblingDom(vNode: VNode, parent: ElementVNode): MaybeDom {
|
|
|
582
582
|
|
|
583
583
|
// Move up to parent — but don't escape portal boundary
|
|
584
584
|
node = node.parent
|
|
585
|
-
if (!node ||
|
|
585
|
+
if (!node || node.flags & FLAG_STATIC_DOM || node === parent) {
|
|
586
586
|
return
|
|
587
587
|
}
|
|
588
588
|
}
|
|
@@ -595,7 +595,7 @@ function findFirstHostDom(vNode: VNode): MaybeDom {
|
|
|
595
595
|
|
|
596
596
|
while (node) {
|
|
597
597
|
if (node.dom) return node.dom
|
|
598
|
-
if (
|
|
598
|
+
if (node.flags & FLAG_STATIC_DOM) return // Don't descend into portals
|
|
599
599
|
node = node.child
|
|
600
600
|
}
|
|
601
601
|
return
|
|
@@ -656,7 +656,9 @@ function commitWork(vNode: VNode) {
|
|
|
656
656
|
currentHostNode = { node: getDomParent(node) }
|
|
657
657
|
hostNodes.push(currentHostNode)
|
|
658
658
|
}
|
|
659
|
-
|
|
659
|
+
if (!(node.flags & FLAG_STATIC_DOM)) {
|
|
660
|
+
commitDom(node as DomVNode, currentHostNode, inheritsPlacement)
|
|
661
|
+
}
|
|
660
662
|
}
|
|
661
663
|
commitSnapshot(node)
|
|
662
664
|
},
|
|
@@ -680,7 +682,6 @@ function commitDom(
|
|
|
680
682
|
hostNode: HostNode,
|
|
681
683
|
inheritsPlacement: boolean
|
|
682
684
|
) {
|
|
683
|
-
if (isPortal(vNode)) return
|
|
684
685
|
if (
|
|
685
686
|
inheritsPlacement ||
|
|
686
687
|
!vNode.dom.isConnected ||
|
|
@@ -720,7 +721,7 @@ function commitDeletion(vNode: VNode) {
|
|
|
720
721
|
|
|
721
722
|
if (dom) {
|
|
722
723
|
if (ref) setDomRef(ref as Kiru.Ref<SomeDom>, null)
|
|
723
|
-
if (dom.isConnected && !
|
|
724
|
+
if (dom.isConnected && !(node.flags & FLAG_STATIC_DOM)) {
|
|
724
725
|
dom.remove()
|
|
725
726
|
}
|
|
726
727
|
delete node.dom
|
package/src/element.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $FRAGMENT, $MEMO } from "./constants.js"
|
|
1
|
+
import { $FRAGMENT, $MEMO, FLAG_MEMO } from "./constants.js"
|
|
2
2
|
import { isMemoFn } from "./memo.js"
|
|
3
3
|
import { isValidElementKeyProp, isValidElementRefProp } from "./props.js"
|
|
4
4
|
|
|
@@ -23,7 +23,7 @@ export function createElement<T extends Kiru.VNode["type"]>(
|
|
|
23
23
|
deletions: null,
|
|
24
24
|
}
|
|
25
25
|
if (isMemoFn(type)) {
|
|
26
|
-
node.
|
|
26
|
+
node.flags |= FLAG_MEMO
|
|
27
27
|
node.arePropsEqual = type[$MEMO].arePropsEqual
|
|
28
28
|
}
|
|
29
29
|
|
package/src/hmr.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { Store } from "./store"
|
|
2
|
-
import type { WatchEffect } from "./signals/watch"
|
|
3
1
|
import { $HMR_ACCEPT } from "./constants.js"
|
|
4
2
|
import { __DEV__ } from "./env.js"
|
|
5
3
|
import { traverseApply } from "./utils.js"
|
|
6
4
|
import { requestUpdate } from "./scheduler.js"
|
|
7
|
-
import { Signal } from "./signals/
|
|
8
|
-
import type {
|
|
5
|
+
import { Signal } from "./signals/base.js"
|
|
6
|
+
import type { WatchEffect } from "./signals/watch.js"
|
|
7
|
+
import type { Store } from "./store.js"
|
|
8
|
+
import type { AppContext } from "./appContext.js"
|
|
9
9
|
|
|
10
10
|
export type HMRAccept<T = {}> = {
|
|
11
11
|
provide: () => T
|
|
@@ -119,7 +119,6 @@ export function createHMRContext() {
|
|
|
119
119
|
}
|
|
120
120
|
if (oldEntry.type === "component" && newEntry.type === "component") {
|
|
121
121
|
window.__kiru!.apps.forEach((ctx) => {
|
|
122
|
-
if (!ctx.mounted || !ctx.rootNode) return
|
|
123
122
|
traverseApply(ctx.rootNode, (vNode) => {
|
|
124
123
|
if (vNode.type === oldEntry.value) {
|
|
125
124
|
vNode.type = newEntry.value as any
|
package/src/index.ts
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createAppContext,
|
|
3
|
-
type AppContext,
|
|
4
|
-
type AppContextOptions,
|
|
5
|
-
} from "./appContext.js"
|
|
6
1
|
import { createKiruGlobalContext } from "./globalContext.js"
|
|
7
2
|
import { __DEV__ } from "./env.js"
|
|
8
|
-
import { KiruError } from "./error.js"
|
|
9
3
|
|
|
10
4
|
export type * from "./types"
|
|
5
|
+
export * from "./signals/index.js"
|
|
11
6
|
export * from "./appContext.js"
|
|
12
7
|
export * from "./context.js"
|
|
13
8
|
export * from "./cloneVNode.js"
|
|
@@ -17,7 +12,6 @@ export * from "./lazy.js"
|
|
|
17
12
|
export { memo } from "./memo.js"
|
|
18
13
|
export * from "./portal.js"
|
|
19
14
|
export * from "./renderToString.js"
|
|
20
|
-
export * from "./signals/index.js"
|
|
21
15
|
export { nextIdle, flushSync, requestUpdate } from "./scheduler.js"
|
|
22
16
|
export * from "./store.js"
|
|
23
17
|
export * from "./transition.js"
|
|
@@ -25,37 +19,3 @@ export * from "./transition.js"
|
|
|
25
19
|
if ("window" in globalThis) {
|
|
26
20
|
globalThis.window.__kiru ??= createKiruGlobalContext()
|
|
27
21
|
}
|
|
28
|
-
|
|
29
|
-
export function mount<T extends Record<string, unknown>>(
|
|
30
|
-
appFunc: (props: T) => JSX.Element,
|
|
31
|
-
options: AppContextOptions,
|
|
32
|
-
appProps?: T
|
|
33
|
-
): Promise<AppContext<T>>
|
|
34
|
-
|
|
35
|
-
export function mount<T extends Record<string, unknown>>(
|
|
36
|
-
appFunc: (props: T) => JSX.Element,
|
|
37
|
-
root: HTMLElement,
|
|
38
|
-
appProps?: T
|
|
39
|
-
): Promise<AppContext<T>>
|
|
40
|
-
|
|
41
|
-
export function mount<T extends Record<string, unknown>>(
|
|
42
|
-
appFunc: (props: T) => JSX.Element,
|
|
43
|
-
optionsOrRoot: HTMLElement | AppContextOptions,
|
|
44
|
-
appProps = {} as T
|
|
45
|
-
): Promise<AppContext<T>> {
|
|
46
|
-
let root: HTMLElement, opts: AppContextOptions | undefined
|
|
47
|
-
if (optionsOrRoot instanceof HTMLElement) {
|
|
48
|
-
root = optionsOrRoot
|
|
49
|
-
opts = { root }
|
|
50
|
-
} else {
|
|
51
|
-
opts = optionsOrRoot
|
|
52
|
-
root = optionsOrRoot.root!
|
|
53
|
-
if (__DEV__) {
|
|
54
|
-
if (!(root instanceof HTMLElement)) {
|
|
55
|
-
throw new KiruError("Root node must be an HTMLElement")
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return createAppContext<T>(appFunc, appProps, opts).mount()
|
|
61
|
-
}
|
package/src/memo.ts
CHANGED
|
@@ -41,8 +41,6 @@ export function memo<T extends Record<string, unknown> = {}>(
|
|
|
41
41
|
|
|
42
42
|
export function isMemoFn(fn: any): fn is MemoFn {
|
|
43
43
|
return (
|
|
44
|
-
typeof fn === "function" &&
|
|
45
|
-
fn[$MEMO] &&
|
|
46
|
-
typeof fn[$MEMO].arePropsEqual === "function"
|
|
44
|
+
typeof fn === "function" && typeof fn[$MEMO]?.arePropsEqual === "function"
|
|
47
45
|
)
|
|
48
46
|
}
|
package/src/portal.ts
CHANGED
|
@@ -1,42 +1,38 @@
|
|
|
1
|
+
import { FLAG_STATIC_DOM } from "./constants.js"
|
|
1
2
|
import { __DEV__ } from "./env.js"
|
|
2
3
|
import { KiruError } from "./error.js"
|
|
3
4
|
import { renderMode } from "./globals.js"
|
|
4
5
|
import { useVNode } from "./hooks/utils.js"
|
|
5
6
|
import { nextIdle, requestUpdate } from "./scheduler.js"
|
|
6
7
|
|
|
7
|
-
export { Portal, isPortal }
|
|
8
|
-
|
|
9
8
|
type PortalProps = {
|
|
10
9
|
children?: JSX.Children
|
|
11
10
|
container: HTMLElement | (() => HTMLElement)
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
function Portal({ children, container }: PortalProps) {
|
|
13
|
+
export function Portal({ children, container }: PortalProps) {
|
|
15
14
|
const vNode = useVNode()
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
15
|
+
if (!vNode.dom) {
|
|
16
|
+
vNode.flags |= FLAG_STATIC_DOM
|
|
17
|
+
switch (renderMode.current) {
|
|
18
|
+
case "dom":
|
|
19
|
+
vNode.dom = typeof container === "function" ? container() : container
|
|
20
|
+
if (!(vNode.dom instanceof HTMLElement)) {
|
|
21
|
+
if (__DEV__) {
|
|
22
|
+
throw new KiruError({
|
|
23
|
+
message: `Invalid portal container, expected HTMLElement, got ${vNode.dom}`,
|
|
24
|
+
vNode: vNode,
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
return null
|
|
25
28
|
}
|
|
29
|
+
return children
|
|
30
|
+
case "hydrate":
|
|
31
|
+
nextIdle(() => requestUpdate(vNode))
|
|
32
|
+
case "stream":
|
|
33
|
+
case "string":
|
|
26
34
|
return null
|
|
27
|
-
|
|
28
|
-
return children
|
|
29
|
-
case "hydrate":
|
|
30
|
-
nextIdle(() => requestUpdate(vNode))
|
|
31
|
-
return null
|
|
32
|
-
case "stream":
|
|
33
|
-
case "string":
|
|
34
|
-
return null
|
|
35
|
+
}
|
|
35
36
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
function isPortal(
|
|
39
|
-
node: Kiru.VNode
|
|
40
|
-
): node is Kiru.VNode & { type: typeof Portal } {
|
|
41
|
-
return node.type === Portal
|
|
37
|
+
return children
|
|
42
38
|
}
|
package/src/props.ts
CHANGED
package/src/reconciler.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
$FRAGMENT,
|
|
3
3
|
FLAG_HAS_MEMO_ANCESTOR,
|
|
4
|
+
FLAG_MEMO,
|
|
4
5
|
FLAG_PLACEMENT,
|
|
5
6
|
FLAG_UPDATE,
|
|
6
7
|
} from "./constants.js"
|
|
7
8
|
import { getVNodeAppContext, isVNode, latest } from "./utils.js"
|
|
8
|
-
import { Signal } from "./signals/
|
|
9
|
+
import { Signal } from "./signals/base.js"
|
|
9
10
|
import { __DEV__ } from "./env.js"
|
|
10
11
|
import { createElement, Fragment } from "./element.js"
|
|
11
12
|
import type { AppContext } from "./appContext.js"
|
|
@@ -459,7 +460,7 @@ function propsChanged(oldProps: VNode["props"], newProps: VNode["props"]) {
|
|
|
459
460
|
function setParent(child: VNode, parent: VNode) {
|
|
460
461
|
child.parent = parent
|
|
461
462
|
child.depth = parent.depth + 1
|
|
462
|
-
if (parent.
|
|
463
|
+
if (parent.flags & (FLAG_MEMO | FLAG_HAS_MEMO_ANCESTOR)) {
|
|
463
464
|
child.flags |= FLAG_HAS_MEMO_ANCESTOR
|
|
464
465
|
}
|
|
465
466
|
}
|
package/src/renderToString.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { node, renderMode } from "./globals.js"
|
|
2
|
-
import { createAppContext } from "./appContext.js"
|
|
3
2
|
import { Fragment } from "./element.js"
|
|
4
3
|
import {
|
|
5
4
|
isVNode,
|
|
@@ -7,22 +6,17 @@ import {
|
|
|
7
6
|
propsToElementAttributes,
|
|
8
7
|
isExoticType,
|
|
9
8
|
} from "./utils.js"
|
|
10
|
-
import { Signal } from "./signals/
|
|
9
|
+
import { Signal } from "./signals/base.js"
|
|
11
10
|
import { $HYDRATION_BOUNDARY, voidElements } from "./constants.js"
|
|
12
11
|
import { assertValidElementProps } from "./props.js"
|
|
13
12
|
import { HYDRATION_BOUNDARY_MARKER } from "./ssr/hydrationBoundary.js"
|
|
14
13
|
import { __DEV__ } from "./env.js"
|
|
15
14
|
|
|
16
|
-
export function renderToString
|
|
17
|
-
appFunc: (props: T) => JSX.Element,
|
|
18
|
-
appProps = {} as T
|
|
19
|
-
) {
|
|
15
|
+
export function renderToString(element: JSX.Element) {
|
|
20
16
|
const prev = renderMode.current
|
|
21
17
|
renderMode.current = "string"
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
})
|
|
25
|
-
const res = renderToString_internal(ctx.rootNode, null, 0)
|
|
18
|
+
const rootNode = Fragment({ children: element })
|
|
19
|
+
const res = renderToString_internal(rootNode, null, 0)
|
|
26
20
|
renderMode.current = prev
|
|
27
21
|
return res
|
|
28
22
|
}
|