kiru 0.45.3 → 0.46.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 +0 -13
- package/dist/appContext.d.ts.map +1 -1
- package/dist/appContext.js +15 -55
- package/dist/appContext.js.map +1 -1
- package/dist/constants.d.ts +5 -7
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +5 -7
- package/dist/constants.js.map +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +2 -4
- package/dist/context.js.map +1 -1
- package/dist/dom.d.ts +2 -2
- package/dist/dom.d.ts.map +1 -1
- package/dist/dom.js +36 -32
- package/dist/dom.js.map +1 -1
- package/dist/globals.d.ts +1 -6
- package/dist/globals.d.ts.map +1 -1
- package/dist/globals.js +1 -5
- package/dist/globals.js.map +1 -1
- package/dist/hmr.d.ts +1 -1
- package/dist/hmr.d.ts.map +1 -1
- package/dist/hmr.js +2 -4
- package/dist/hmr.js.map +1 -1
- package/dist/hooks/useViewTransition.d.ts.map +1 -1
- package/dist/hooks/useViewTransition.js +3 -3
- package/dist/hooks/useViewTransition.js.map +1 -1
- package/dist/hooks/utils.d.ts +1 -5
- package/dist/hooks/utils.d.ts.map +1 -1
- package/dist/hooks/utils.js +8 -20
- package/dist/hooks/utils.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/lazy.d.ts.map +1 -1
- package/dist/lazy.js +4 -4
- package/dist/lazy.js.map +1 -1
- package/dist/portal.d.ts.map +1 -1
- package/dist/portal.js +2 -3
- package/dist/portal.js.map +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 +105 -79
- package/dist/reconciler.js.map +1 -1
- package/dist/renderToString.d.ts.map +1 -1
- package/dist/renderToString.js +5 -8
- package/dist/renderToString.js.map +1 -1
- package/dist/router/router.d.ts.map +1 -1
- package/dist/router/router.js +5 -6
- package/dist/router/router.js.map +1 -1
- package/dist/scheduler.d.ts +13 -11
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +369 -390
- package/dist/scheduler.js.map +1 -1
- package/dist/signals/base.d.ts +4 -4
- package/dist/signals/base.d.ts.map +1 -1
- package/dist/signals/base.js +38 -24
- package/dist/signals/base.js.map +1 -1
- package/dist/signals/computed.d.ts +2 -2
- package/dist/signals/computed.d.ts.map +1 -1
- package/dist/signals/computed.js +11 -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/globals.d.ts +2 -2
- package/dist/signals/globals.d.ts.map +1 -1
- package/dist/signals/globals.js.map +1 -1
- package/dist/signals/jsx.d.ts +4 -3
- package/dist/signals/jsx.d.ts.map +1 -1
- package/dist/signals/jsx.js +1 -1
- package/dist/signals/jsx.js.map +1 -1
- package/dist/signals/types.d.ts +2 -2
- 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/server.d.ts.map +1 -1
- package/dist/ssr/server.js +1 -5
- package/dist/ssr/server.js.map +1 -1
- package/dist/types.d.ts +9 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +17 -17
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/appContext.ts +21 -67
- package/src/constants.ts +8 -7
- package/src/context.ts +2 -4
- package/src/dom.ts +50 -29
- package/src/globals.ts +1 -9
- package/src/hmr.ts +3 -5
- package/src/hooks/useViewTransition.ts +3 -3
- package/src/hooks/utils.ts +7 -22
- package/src/index.ts +3 -3
- package/src/lazy.ts +4 -4
- package/src/portal.ts +2 -3
- package/src/props.ts +1 -1
- package/src/reconciler.ts +116 -90
- package/src/renderToString.ts +5 -8
- package/src/router/router.ts +4 -6
- package/src/scheduler.ts +374 -408
- package/src/signals/base.ts +40 -33
- package/src/signals/computed.ts +8 -3
- package/src/signals/effect.ts +1 -1
- package/src/signals/globals.ts +2 -2
- package/src/signals/jsx.ts +12 -11
- package/src/signals/types.ts +2 -2
- package/src/signals/utils.ts +1 -1
- package/src/ssr/server.ts +1 -5
- package/src/types.ts +9 -2
- package/src/utils.ts +26 -21
- package/dist/flags.d.ts +0 -6
- package/dist/flags.d.ts.map +0 -1
- package/dist/flags.js +0 -16
- package/dist/flags.js.map +0 -1
- package/src/flags.ts +0 -15
package/src/hmr.ts
CHANGED
|
@@ -2,8 +2,9 @@ import type { Store } from "./store"
|
|
|
2
2
|
import type { WatchEffect } from "./signals/watch"
|
|
3
3
|
import { $HMR_ACCEPT } from "./constants.js"
|
|
4
4
|
import { __DEV__ } from "./env.js"
|
|
5
|
-
import { Signal } from "./signals/base.js"
|
|
6
5
|
import { traverseApply } from "./utils.js"
|
|
6
|
+
import { requestUpdate } from "./scheduler.js"
|
|
7
|
+
import { Signal } from "./signals/index.js"
|
|
7
8
|
import type { AppContext } from "./appContext"
|
|
8
9
|
|
|
9
10
|
export type HMRAccept<T = {}> = {
|
|
@@ -124,15 +125,12 @@ export function createHMRContext() {
|
|
|
124
125
|
vNode.type = newEntry.value as any
|
|
125
126
|
dirtiedApps.add(ctx)
|
|
126
127
|
vNode.hmrUpdated = true
|
|
127
|
-
if (vNode.prev) {
|
|
128
|
-
vNode.prev.type = newEntry.value as any
|
|
129
|
-
}
|
|
130
128
|
}
|
|
131
129
|
})
|
|
132
130
|
})
|
|
133
131
|
}
|
|
134
132
|
}
|
|
135
|
-
dirtiedApps.forEach((ctx) => ctx.requestUpdate())
|
|
133
|
+
dirtiedApps.forEach((ctx) => ctx.rootNode && requestUpdate(ctx.rootNode))
|
|
136
134
|
isModuleReplacementExecution = false
|
|
137
135
|
|
|
138
136
|
if (tmpUnnamedWatchers.length) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { flushSync } from "../scheduler.js"
|
|
2
|
+
import { node } from "../globals.js"
|
|
2
3
|
import { noop } from "../utils.js"
|
|
3
4
|
import { sideEffectsEnabled } from "./utils.js"
|
|
4
5
|
|
|
@@ -12,7 +13,6 @@ import { sideEffectsEnabled } from "./utils.js"
|
|
|
12
13
|
*/
|
|
13
14
|
export function useViewTransition() {
|
|
14
15
|
if (!sideEffectsEnabled()) return noop
|
|
15
|
-
const appCtx = ctx.current
|
|
16
16
|
return (callback: () => void) => {
|
|
17
17
|
if (node.current) {
|
|
18
18
|
throw new Error("useViewTransition can't be called during rendering.")
|
|
@@ -20,7 +20,7 @@ export function useViewTransition() {
|
|
|
20
20
|
if (!document.startViewTransition) return callback()
|
|
21
21
|
document.startViewTransition(() => {
|
|
22
22
|
callback()
|
|
23
|
-
|
|
23
|
+
flushSync()
|
|
24
24
|
})
|
|
25
25
|
}
|
|
26
26
|
}
|
package/src/hooks/utils.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { KiruError } from "../error.js"
|
|
2
2
|
import { __DEV__ } from "../env.js"
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { hookIndex, node } from "../globals.js"
|
|
4
|
+
import { noop } from "../utils.js"
|
|
5
|
+
import { requestUpdate } from "../scheduler.js"
|
|
5
6
|
export { sideEffectsEnabled } from "../utils.js"
|
|
6
7
|
export {
|
|
7
8
|
cleanupHook,
|
|
8
9
|
depsRequireChange,
|
|
9
10
|
useHook,
|
|
10
11
|
useVNode,
|
|
11
|
-
useAppContext,
|
|
12
12
|
useHookDebugGroup,
|
|
13
13
|
useRequestUpdate,
|
|
14
14
|
HookDebugGroupAction,
|
|
@@ -46,19 +46,7 @@ const useHookDebugGroup = (name: string, action: HookDebugGroupAction) => {
|
|
|
46
46
|
const useRequestUpdate = () => {
|
|
47
47
|
const n = node.current
|
|
48
48
|
if (!n) error_hookMustBeCalledTopLevel("useRequestUpdate")
|
|
49
|
-
|
|
50
|
-
return () => ctx.requestUpdate(n)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Used to obtain the 'AppContext' for the current component.
|
|
55
|
-
*/
|
|
56
|
-
const useAppContext = () => {
|
|
57
|
-
if (!node.current) error_hookMustBeCalledTopLevel("useAppContext")
|
|
58
|
-
const ctx = nodeToCtxMap.get(node.current)
|
|
59
|
-
if (!ctx)
|
|
60
|
-
error_hookMustBeCalledTopLevel("[kiru]: unable to find node's AppContext")
|
|
61
|
-
return ctx
|
|
49
|
+
return () => requestUpdate(n)
|
|
62
50
|
}
|
|
63
51
|
|
|
64
52
|
/**
|
|
@@ -153,12 +141,9 @@ function useHook<
|
|
|
153
141
|
;(vNode.effects ??= []).push(callback)
|
|
154
142
|
}
|
|
155
143
|
|
|
156
|
-
const appCtx = ctx.current
|
|
157
144
|
const index = hookIndex.current++
|
|
158
145
|
|
|
159
|
-
let oldHook = (
|
|
160
|
-
vNode.prev ? vNode.prev.hooks?.at(index) : vNode.hooks?.at(index)
|
|
161
|
-
) as HookState<T> | undefined
|
|
146
|
+
let oldHook = vNode.hooks?.at(index) as HookState<T> | undefined
|
|
162
147
|
|
|
163
148
|
if (__DEV__) {
|
|
164
149
|
currentHookName = hookName
|
|
@@ -197,7 +182,7 @@ function useHook<
|
|
|
197
182
|
hook,
|
|
198
183
|
isInit: !oldHook,
|
|
199
184
|
isHMR: vNode.hmrUpdated,
|
|
200
|
-
update: () =>
|
|
185
|
+
update: () => requestUpdate(vNode),
|
|
201
186
|
queueEffect,
|
|
202
187
|
vNode,
|
|
203
188
|
index,
|
|
@@ -223,7 +208,7 @@ function useHook<
|
|
|
223
208
|
const res = (callback as HookCallback<T>)({
|
|
224
209
|
hook,
|
|
225
210
|
isInit: !oldHook,
|
|
226
|
-
update: () =>
|
|
211
|
+
update: () => requestUpdate(vNode),
|
|
227
212
|
queueEffect,
|
|
228
213
|
vNode,
|
|
229
214
|
index,
|
package/src/index.ts
CHANGED
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
type AppContext,
|
|
4
4
|
type AppContextOptions,
|
|
5
5
|
} from "./appContext.js"
|
|
6
|
-
import { ctx } from "./globals.js"
|
|
7
6
|
import { createKiruGlobalContext } from "./globalContext.js"
|
|
8
7
|
import { __DEV__ } from "./env.js"
|
|
9
8
|
import { KiruError } from "./error.js"
|
|
@@ -19,6 +18,7 @@ export { memo } from "./memo.js"
|
|
|
19
18
|
export * from "./portal.js"
|
|
20
19
|
export * from "./renderToString.js"
|
|
21
20
|
export * from "./signals/index.js"
|
|
21
|
+
export { nextIdle, flushSync, requestUpdate } from "./scheduler.js"
|
|
22
22
|
export * from "./store.js"
|
|
23
23
|
export * from "./transition.js"
|
|
24
24
|
|
|
@@ -56,6 +56,6 @@ export function mount<T extends Record<string, unknown>>(
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
|
-
|
|
60
|
-
return
|
|
59
|
+
|
|
60
|
+
return createAppContext<T>(appFunc, appProps, opts).mount()
|
|
61
61
|
}
|
package/src/lazy.ts
CHANGED
|
@@ -4,8 +4,9 @@ import { KiruError } from "./error.js"
|
|
|
4
4
|
import { node, renderMode } from "./globals.js"
|
|
5
5
|
import { useContext } from "./hooks/useContext.js"
|
|
6
6
|
import { useRef } from "./hooks/useRef.js"
|
|
7
|
-
import {
|
|
7
|
+
import { useRequestUpdate } from "./hooks/utils.js"
|
|
8
8
|
import { hydrationStack } from "./hydration.js"
|
|
9
|
+
import { flushSync, nextIdle } from "./scheduler.js"
|
|
9
10
|
import {
|
|
10
11
|
HYDRATION_BOUNDARY_MARKER,
|
|
11
12
|
HydrationBoundaryContext,
|
|
@@ -85,7 +86,6 @@ export function lazy<T extends LazyImportValue>(
|
|
|
85
86
|
): Kiru.FC<LazyComponentProps<T>> {
|
|
86
87
|
function LazyComponent(props: LazyComponentProps<T>) {
|
|
87
88
|
const { fallback = null, ...rest } = props
|
|
88
|
-
const appCtx = useAppContext()
|
|
89
89
|
const hydrationCtx = useContext(HydrationBoundaryContext, false)
|
|
90
90
|
const needsHydration = useRef(
|
|
91
91
|
hydrationCtx && renderMode.current === "hydrate"
|
|
@@ -154,7 +154,7 @@ export function lazy<T extends LazyImportValue>(
|
|
|
154
154
|
const hydrate = () => {
|
|
155
155
|
if (needsHydration.current === false) return
|
|
156
156
|
|
|
157
|
-
|
|
157
|
+
nextIdle(() => {
|
|
158
158
|
delete thisNode.lastChildDom
|
|
159
159
|
needsHydration.current = false
|
|
160
160
|
hydrationStack.push(parent)
|
|
@@ -169,7 +169,7 @@ export function lazy<T extends LazyImportValue>(
|
|
|
169
169
|
*/
|
|
170
170
|
requestUpdate()
|
|
171
171
|
renderMode.current = "hydrate"
|
|
172
|
-
|
|
172
|
+
flushSync()
|
|
173
173
|
renderMode.current = prev
|
|
174
174
|
for (const child of childNodes) {
|
|
175
175
|
if (child instanceof Element) {
|
package/src/portal.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { __DEV__ } from "./env.js"
|
|
|
2
2
|
import { KiruError } from "./error.js"
|
|
3
3
|
import { renderMode } from "./globals.js"
|
|
4
4
|
import { useVNode } from "./hooks/utils.js"
|
|
5
|
-
import {
|
|
5
|
+
import { nextIdle, requestUpdate } from "./scheduler.js"
|
|
6
6
|
|
|
7
7
|
export { Portal, isPortal }
|
|
8
8
|
|
|
@@ -27,8 +27,7 @@ function Portal({ children, container }: PortalProps) {
|
|
|
27
27
|
}
|
|
28
28
|
return children
|
|
29
29
|
case "hydrate":
|
|
30
|
-
|
|
31
|
-
ctx.scheduler?.nextIdle(() => ctx.requestUpdate(vNode))
|
|
30
|
+
nextIdle(() => requestUpdate(vNode))
|
|
32
31
|
return null
|
|
33
32
|
case "stream":
|
|
34
33
|
case "string":
|
package/src/props.ts
CHANGED
package/src/reconciler.ts
CHANGED
|
@@ -1,14 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
$FRAGMENT,
|
|
3
|
+
FLAG_HAS_MEMO_ANCESTOR,
|
|
4
|
+
FLAG_PLACEMENT,
|
|
5
|
+
FLAG_UPDATE,
|
|
6
|
+
} from "./constants.js"
|
|
7
|
+
import { getVNodeAppContext, isVNode, latest } from "./utils.js"
|
|
8
|
+
import { Signal } from "./signals/index.js"
|
|
4
9
|
import { __DEV__ } from "./env.js"
|
|
5
10
|
import { createElement, Fragment } from "./element.js"
|
|
6
|
-
import {
|
|
7
|
-
import { ctx } from "./globals.js"
|
|
11
|
+
import type { AppContext } from "./appContext.js"
|
|
8
12
|
|
|
9
13
|
type VNode = Kiru.VNode
|
|
14
|
+
let appCtx: AppContext
|
|
10
15
|
|
|
11
16
|
export function reconcileChildren(parent: VNode, children: unknown) {
|
|
17
|
+
if (__DEV__) {
|
|
18
|
+
appCtx = getVNodeAppContext(parent)!
|
|
19
|
+
}
|
|
12
20
|
if (Array.isArray(children)) {
|
|
13
21
|
if (__DEV__) {
|
|
14
22
|
// array children are 'tagged' during parent reconciliation pass
|
|
@@ -43,13 +51,11 @@ function reconcileSingleChild(parent: VNode, child: unknown) {
|
|
|
43
51
|
const existingChildren = mapRemainingChildren(oldChild)
|
|
44
52
|
const newNode = updateFromMap(existingChildren, parent, 0, child)
|
|
45
53
|
if (newNode !== null) {
|
|
46
|
-
|
|
54
|
+
const prev = newNode.prev
|
|
55
|
+
if (prev !== null) {
|
|
56
|
+
const key = prev.props.key
|
|
47
57
|
// node persisted, remove it from the list so it doesn't get deleted
|
|
48
|
-
existingChildren.delete(
|
|
49
|
-
newNode.prev.props.key === undefined
|
|
50
|
-
? newNode.prev.index
|
|
51
|
-
: newNode.prev.props.key
|
|
52
|
-
)
|
|
58
|
+
existingChildren.delete(key === undefined ? prev.index : key)
|
|
53
59
|
}
|
|
54
60
|
placeChild(newNode, 0, 0)
|
|
55
61
|
}
|
|
@@ -68,7 +74,7 @@ function reconcileChildrenArray(parent: VNode, children: unknown[]) {
|
|
|
68
74
|
let lastPlacedIndex = 0
|
|
69
75
|
let newIdx = 0
|
|
70
76
|
|
|
71
|
-
for (;
|
|
77
|
+
for (; oldChild !== null && newIdx < children.length; newIdx++) {
|
|
72
78
|
if (oldChild.index > newIdx) {
|
|
73
79
|
nextOldChild = oldChild
|
|
74
80
|
oldChild = null
|
|
@@ -128,13 +134,11 @@ function reconcileChildrenArray(parent: VNode, children: unknown[]) {
|
|
|
128
134
|
children[newIdx]
|
|
129
135
|
)
|
|
130
136
|
if (newNode !== null) {
|
|
131
|
-
|
|
137
|
+
const prev = newNode.prev
|
|
138
|
+
if (prev !== null) {
|
|
139
|
+
const key = prev.props.key
|
|
132
140
|
// node persisted, remove it from the list so it doesn't get deleted
|
|
133
|
-
existingChildren.delete(
|
|
134
|
-
newNode.prev.props.key === undefined
|
|
135
|
-
? newNode.prev.index
|
|
136
|
-
: newNode.prev.props.key
|
|
137
|
-
)
|
|
141
|
+
existingChildren.delete(key === undefined ? prev.index : key)
|
|
138
142
|
}
|
|
139
143
|
lastPlacedIndex = placeChild(newNode, lastPlacedIndex, newIdx)
|
|
140
144
|
if (prevNewChild === null) {
|
|
@@ -192,24 +196,27 @@ function updateTextNode(
|
|
|
192
196
|
) {
|
|
193
197
|
if (oldChild === null || oldChild.type !== "#text") {
|
|
194
198
|
if (__DEV__) {
|
|
195
|
-
|
|
199
|
+
dev_emitCreateNode()
|
|
196
200
|
}
|
|
197
201
|
const newChild = createElement("#text", { nodeValue: content })
|
|
198
202
|
setParent(newChild, parent)
|
|
199
203
|
return newChild
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (__DEV__) {
|
|
207
|
+
dev_emitUpdateNode()
|
|
208
|
+
}
|
|
209
|
+
const prev = oldChild.props.nodeValue
|
|
210
|
+
if (prev !== content) {
|
|
204
211
|
oldChild.props.nodeValue = content
|
|
205
|
-
oldChild.flags
|
|
206
|
-
oldChild.sibling = null
|
|
207
|
-
return oldChild
|
|
212
|
+
oldChild.flags |= FLAG_UPDATE
|
|
208
213
|
}
|
|
214
|
+
oldChild.sibling = null
|
|
215
|
+
return oldChild
|
|
209
216
|
}
|
|
210
217
|
|
|
211
218
|
function updateNode(parent: VNode, oldChild: VNode | null, newChild: VNode) {
|
|
212
|
-
let nodeType = newChild
|
|
219
|
+
let { type: nodeType, props: newProps } = newChild
|
|
213
220
|
if (__DEV__) {
|
|
214
221
|
if (typeof nodeType === "function") {
|
|
215
222
|
nodeType = latest(nodeType)
|
|
@@ -219,25 +226,31 @@ function updateNode(parent: VNode, oldChild: VNode | null, newChild: VNode) {
|
|
|
219
226
|
return updateFragment(
|
|
220
227
|
parent,
|
|
221
228
|
oldChild,
|
|
222
|
-
(
|
|
223
|
-
|
|
229
|
+
(newProps.children as VNode[]) || [],
|
|
230
|
+
newProps
|
|
224
231
|
)
|
|
225
232
|
}
|
|
226
233
|
if (oldChild?.type === nodeType) {
|
|
227
234
|
if (__DEV__) {
|
|
228
|
-
|
|
235
|
+
dev_emitUpdateNode()
|
|
229
236
|
}
|
|
230
237
|
oldChild.index = 0
|
|
231
|
-
oldChild.props = newChild.props
|
|
232
238
|
oldChild.sibling = null
|
|
233
|
-
|
|
239
|
+
if (typeof nodeType === "string") {
|
|
240
|
+
if (propsChanged(oldChild.props, newProps)) {
|
|
241
|
+
oldChild.flags |= FLAG_UPDATE
|
|
242
|
+
}
|
|
243
|
+
} else {
|
|
244
|
+
oldChild.flags |= FLAG_UPDATE
|
|
245
|
+
}
|
|
246
|
+
oldChild.props = newProps
|
|
234
247
|
oldChild.memoizedProps = newChild.memoizedProps
|
|
235
248
|
return oldChild
|
|
236
249
|
}
|
|
237
250
|
if (__DEV__) {
|
|
238
|
-
|
|
251
|
+
dev_emitCreateNode()
|
|
239
252
|
}
|
|
240
|
-
const created = createElement(nodeType,
|
|
253
|
+
const created = createElement(nodeType, newProps)
|
|
241
254
|
setParent(created, parent)
|
|
242
255
|
return created
|
|
243
256
|
}
|
|
@@ -250,17 +263,17 @@ function updateFragment(
|
|
|
250
263
|
) {
|
|
251
264
|
if (oldChild === null || oldChild.type !== $FRAGMENT) {
|
|
252
265
|
if (__DEV__) {
|
|
253
|
-
|
|
266
|
+
dev_emitCreateNode()
|
|
254
267
|
}
|
|
255
268
|
const el = createElement($FRAGMENT, { children, ...newProps })
|
|
256
269
|
setParent(el, parent)
|
|
257
270
|
return el
|
|
258
271
|
}
|
|
259
272
|
if (__DEV__) {
|
|
260
|
-
|
|
273
|
+
dev_emitUpdateNode()
|
|
261
274
|
}
|
|
262
275
|
oldChild.props = { ...oldChild.props, ...newProps, children }
|
|
263
|
-
oldChild.flags
|
|
276
|
+
oldChild.flags |= FLAG_UPDATE
|
|
264
277
|
oldChild.sibling = null
|
|
265
278
|
return oldChild
|
|
266
279
|
}
|
|
@@ -272,7 +285,7 @@ function createChild(parent: VNode, child: unknown): VNode | null {
|
|
|
272
285
|
typeof child === "bigint"
|
|
273
286
|
) {
|
|
274
287
|
if (__DEV__) {
|
|
275
|
-
|
|
288
|
+
dev_emitCreateNode()
|
|
276
289
|
}
|
|
277
290
|
const el = createElement("#text", {
|
|
278
291
|
nodeValue: "" + child,
|
|
@@ -283,7 +296,7 @@ function createChild(parent: VNode, child: unknown): VNode | null {
|
|
|
283
296
|
|
|
284
297
|
if (Signal.isSignal(child)) {
|
|
285
298
|
if (__DEV__) {
|
|
286
|
-
|
|
299
|
+
dev_emitCreateNode()
|
|
287
300
|
}
|
|
288
301
|
const el = createElement("#text", {
|
|
289
302
|
nodeValue: child,
|
|
@@ -294,17 +307,17 @@ function createChild(parent: VNode, child: unknown): VNode | null {
|
|
|
294
307
|
|
|
295
308
|
if (isVNode(child)) {
|
|
296
309
|
if (__DEV__) {
|
|
297
|
-
|
|
310
|
+
dev_emitCreateNode()
|
|
298
311
|
}
|
|
299
312
|
const newNode = createElement(child.type, child.props)
|
|
300
313
|
setParent(newNode, parent)
|
|
301
|
-
newNode.flags
|
|
314
|
+
newNode.flags |= FLAG_PLACEMENT
|
|
302
315
|
return newNode
|
|
303
316
|
}
|
|
304
317
|
|
|
305
318
|
if (Array.isArray(child)) {
|
|
306
319
|
if (__DEV__) {
|
|
307
|
-
|
|
320
|
+
dev_emitCreateNode()
|
|
308
321
|
markListChild(child)
|
|
309
322
|
}
|
|
310
323
|
const el = Fragment({ children: child })
|
|
@@ -316,22 +329,22 @@ function createChild(parent: VNode, child: unknown): VNode | null {
|
|
|
316
329
|
}
|
|
317
330
|
|
|
318
331
|
function placeChild(
|
|
319
|
-
child: VNode
|
|
332
|
+
child: VNode,
|
|
320
333
|
lastPlacedIndex: number,
|
|
321
334
|
newIndex: number
|
|
322
335
|
): number {
|
|
323
|
-
if (child === null) return lastPlacedIndex
|
|
324
336
|
child.index = newIndex
|
|
325
|
-
|
|
326
|
-
|
|
337
|
+
const prev = child.prev
|
|
338
|
+
if (prev !== null) {
|
|
339
|
+
const oldIndex = prev.index
|
|
327
340
|
if (oldIndex < lastPlacedIndex) {
|
|
328
|
-
child.flags
|
|
341
|
+
child.flags |= FLAG_PLACEMENT
|
|
329
342
|
return lastPlacedIndex
|
|
330
343
|
} else {
|
|
331
344
|
return oldIndex
|
|
332
345
|
}
|
|
333
346
|
} else {
|
|
334
|
-
child.flags
|
|
347
|
+
child.flags |= FLAG_PLACEMENT
|
|
335
348
|
return lastPlacedIndex
|
|
336
349
|
}
|
|
337
350
|
}
|
|
@@ -352,8 +365,6 @@ function updateFromMap(
|
|
|
352
365
|
const oldChild = existingChildren.get(index)
|
|
353
366
|
if (oldChild) {
|
|
354
367
|
if (oldChild.props.nodeValue === child) {
|
|
355
|
-
oldChild.flags = flags.set(oldChild.flags, FLAG.UPDATE)
|
|
356
|
-
oldChild.props.nodeValue = child
|
|
357
368
|
return oldChild
|
|
358
369
|
}
|
|
359
370
|
if (
|
|
@@ -365,40 +376,46 @@ function updateFromMap(
|
|
|
365
376
|
}
|
|
366
377
|
|
|
367
378
|
if (__DEV__) {
|
|
368
|
-
|
|
379
|
+
dev_emitCreateNode()
|
|
369
380
|
}
|
|
370
381
|
const newChild = createElement("#text", {
|
|
371
382
|
nodeValue: child,
|
|
372
383
|
})
|
|
373
384
|
setParent(newChild, parent)
|
|
374
|
-
newChild.flags
|
|
385
|
+
newChild.flags |= FLAG_PLACEMENT
|
|
375
386
|
newChild.index = index
|
|
376
387
|
return newChild
|
|
377
388
|
}
|
|
378
389
|
|
|
379
390
|
if (isVNode(child)) {
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
)
|
|
383
|
-
if (oldChild?.type ===
|
|
391
|
+
const { type, props: newProps } = child
|
|
392
|
+
const key = newProps.key
|
|
393
|
+
const oldChild = existingChildren.get(key === undefined ? index : key)
|
|
394
|
+
if (oldChild?.type === type) {
|
|
384
395
|
if (__DEV__) {
|
|
385
|
-
|
|
396
|
+
dev_emitUpdateNode()
|
|
386
397
|
}
|
|
387
|
-
|
|
388
|
-
|
|
398
|
+
if (typeof type === "string") {
|
|
399
|
+
if (propsChanged(oldChild.props, newProps)) {
|
|
400
|
+
oldChild.flags |= FLAG_UPDATE
|
|
401
|
+
}
|
|
402
|
+
} else {
|
|
403
|
+
oldChild.flags |= FLAG_UPDATE
|
|
404
|
+
}
|
|
405
|
+
oldChild.props = newProps
|
|
389
406
|
oldChild.sibling = null
|
|
390
407
|
oldChild.index = index
|
|
391
408
|
return oldChild
|
|
392
|
-
} else {
|
|
393
|
-
if (__DEV__) {
|
|
394
|
-
emitCreateNode()
|
|
395
|
-
}
|
|
396
|
-
const newChild = createElement(child.type, child.props)
|
|
397
|
-
setParent(newChild, parent)
|
|
398
|
-
newChild.flags = flags.set(newChild.flags, FLAG.PLACEMENT)
|
|
399
|
-
newChild.index = index
|
|
400
|
-
return newChild
|
|
401
409
|
}
|
|
410
|
+
|
|
411
|
+
if (__DEV__) {
|
|
412
|
+
dev_emitCreateNode()
|
|
413
|
+
}
|
|
414
|
+
const newChild = createElement(child.type, child.props)
|
|
415
|
+
setParent(newChild, parent)
|
|
416
|
+
newChild.flags |= FLAG_PLACEMENT
|
|
417
|
+
newChild.index = index
|
|
418
|
+
return newChild
|
|
402
419
|
}
|
|
403
420
|
|
|
404
421
|
if (Array.isArray(child)) {
|
|
@@ -408,42 +425,53 @@ function updateFromMap(
|
|
|
408
425
|
}
|
|
409
426
|
if (oldChild) {
|
|
410
427
|
if (__DEV__) {
|
|
411
|
-
|
|
428
|
+
dev_emitUpdateNode()
|
|
412
429
|
}
|
|
413
|
-
oldChild.flags
|
|
430
|
+
oldChild.flags |= FLAG_UPDATE
|
|
414
431
|
oldChild.props.children = child
|
|
415
432
|
return oldChild
|
|
416
|
-
} else {
|
|
417
|
-
if (__DEV__) {
|
|
418
|
-
emitCreateNode()
|
|
419
|
-
}
|
|
420
|
-
const newChild = Fragment({ children: child })
|
|
421
|
-
setParent(newChild, parent)
|
|
422
|
-
newChild.flags = flags.set(newChild.flags, FLAG.PLACEMENT)
|
|
423
|
-
newChild.index = index
|
|
424
|
-
return newChild
|
|
425
433
|
}
|
|
434
|
+
|
|
435
|
+
if (__DEV__) {
|
|
436
|
+
dev_emitCreateNode()
|
|
437
|
+
}
|
|
438
|
+
const newChild = Fragment({ children: child })
|
|
439
|
+
setParent(newChild, parent)
|
|
440
|
+
newChild.flags |= FLAG_PLACEMENT
|
|
441
|
+
newChild.index = index
|
|
442
|
+
return newChild
|
|
426
443
|
}
|
|
427
444
|
|
|
428
445
|
return null
|
|
429
446
|
}
|
|
430
447
|
|
|
431
|
-
function
|
|
448
|
+
function propsChanged(oldProps: VNode["props"], newProps: VNode["props"]) {
|
|
449
|
+
const aKeys = Object.keys(oldProps)
|
|
450
|
+
const bKeys = Object.keys(newProps)
|
|
451
|
+
if (aKeys.length !== bKeys.length) return true
|
|
452
|
+
for (let key of aKeys) {
|
|
453
|
+
if (key === "children" || key === "key") continue
|
|
454
|
+
if (oldProps[key] !== newProps[key]) return true
|
|
455
|
+
}
|
|
456
|
+
return false
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
function setParent(child: VNode, parent: VNode) {
|
|
432
460
|
child.parent = parent
|
|
433
461
|
child.depth = parent.depth + 1
|
|
434
|
-
if (parent.isMemoized ||
|
|
435
|
-
child.flags
|
|
462
|
+
if (parent.isMemoized || parent.flags & FLAG_HAS_MEMO_ANCESTOR) {
|
|
463
|
+
child.flags |= FLAG_HAS_MEMO_ANCESTOR
|
|
436
464
|
}
|
|
437
465
|
}
|
|
438
466
|
|
|
439
|
-
function
|
|
467
|
+
function dev_emitUpdateNode() {
|
|
440
468
|
if (!("window" in globalThis)) return
|
|
441
|
-
window.__kiru?.profilingContext?.emit("updateNode",
|
|
469
|
+
window.__kiru?.profilingContext?.emit("updateNode", appCtx)
|
|
442
470
|
}
|
|
443
471
|
|
|
444
|
-
function
|
|
472
|
+
function dev_emitCreateNode() {
|
|
445
473
|
if (!("window" in globalThis)) return
|
|
446
|
-
window.__kiru?.profilingContext?.emit("createNode",
|
|
474
|
+
window.__kiru?.profilingContext?.emit("createNode", appCtx)
|
|
447
475
|
}
|
|
448
476
|
|
|
449
477
|
const $LIST_CHILD = Symbol("kiru:marked-list-child")
|
|
@@ -454,10 +482,8 @@ function markListChild(children: unknown[]) {
|
|
|
454
482
|
function mapRemainingChildren(child: VNode | null) {
|
|
455
483
|
const map: Map<JSX.ElementKey, VNode> = new Map()
|
|
456
484
|
while (child) {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
child
|
|
460
|
-
)
|
|
485
|
+
const key = child.props.key
|
|
486
|
+
map.set(key === undefined ? child.index : key, child)
|
|
461
487
|
child = child.sibling
|
|
462
488
|
}
|
|
463
489
|
return map
|
package/src/renderToString.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { node, renderMode } from "./globals.js"
|
|
2
2
|
import { createAppContext } from "./appContext.js"
|
|
3
3
|
import { Fragment } from "./element.js"
|
|
4
4
|
import {
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
propsToElementAttributes,
|
|
8
8
|
isExoticType,
|
|
9
9
|
} from "./utils.js"
|
|
10
|
-
import { Signal } from "./signals/
|
|
10
|
+
import { Signal } from "./signals/index.js"
|
|
11
11
|
import { $HYDRATION_BOUNDARY, voidElements } from "./constants.js"
|
|
12
12
|
import { assertValidElementProps } from "./props.js"
|
|
13
13
|
import { HYDRATION_BOUNDARY_MARKER } from "./ssr/hydrationBoundary.js"
|
|
@@ -19,13 +19,11 @@ export function renderToString<T extends Record<string, unknown>>(
|
|
|
19
19
|
) {
|
|
20
20
|
const prev = renderMode.current
|
|
21
21
|
renderMode.current = "string"
|
|
22
|
-
const
|
|
23
|
-
const c = (ctx.current = createAppContext(appFunc, appProps, {
|
|
22
|
+
const ctx = createAppContext(appFunc, appProps, {
|
|
24
23
|
rootType: Fragment,
|
|
25
|
-
})
|
|
26
|
-
const res = renderToString_internal(
|
|
24
|
+
})
|
|
25
|
+
const res = renderToString_internal(ctx.rootNode, null, 0)
|
|
27
26
|
renderMode.current = prev
|
|
28
|
-
ctx.current = prevCtx
|
|
29
27
|
return res
|
|
30
28
|
}
|
|
31
29
|
|
|
@@ -65,7 +63,6 @@ function renderToString_internal(
|
|
|
65
63
|
}
|
|
66
64
|
|
|
67
65
|
if (typeof type !== "string") {
|
|
68
|
-
nodeToCtxMap.set(el, ctx.current)
|
|
69
66
|
node.current = el
|
|
70
67
|
const res = type(props)
|
|
71
68
|
node.current = null
|