kiru 0.47.0 → 0.48.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.
- package/dist/constants.d.ts +4 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +5 -3
- package/dist/constants.js.map +1 -1
- package/dist/dom.d.ts.map +1 -1
- package/dist/dom.js +124 -52
- 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 -2
- package/dist/hmr.d.ts.map +1 -1
- package/dist/hmr.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- 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/props.js +1 -1
- package/dist/props.js.map +1 -1
- package/dist/reconciler.d.ts.map +1 -1
- package/dist/reconciler.js +14 -11
- package/dist/reconciler.js.map +1 -1
- package/dist/renderToString.js +1 -1
- package/dist/renderToString.js.map +1 -1
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +37 -142
- 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/server.js +1 -1
- package/dist/ssr/server.js.map +1 -1
- package/dist/swr.d.ts +1 -1
- package/dist/swr.d.ts.map +1 -1
- package/dist/swr.js +1 -1
- package/dist/swr.js.map +1 -1
- package/dist/types.d.ts +0 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +1 -10
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +3 -47
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +7 -3
- package/src/dom.ts +130 -56
- package/src/element.ts +2 -2
- package/src/hmr.ts +4 -3
- package/src/index.ts +1 -1
- package/src/memo.ts +1 -3
- package/src/props.ts +1 -1
- package/src/reconciler.ts +14 -16
- package/src/renderToString.ts +1 -1
- package/src/scheduler.ts +47 -144
- 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/server.ts +1 -1
- package/src/swr.ts +1 -1
- package/src/types.ts +0 -1
- package/src/utils.ts +1 -66
package/src/scheduler.ts
CHANGED
|
@@ -7,6 +7,9 @@ import {
|
|
|
7
7
|
$CONTEXT_PROVIDER,
|
|
8
8
|
CONSECUTIVE_DIRTY_LIMIT,
|
|
9
9
|
FLAG_DELETION,
|
|
10
|
+
FLAG_DIRTY,
|
|
11
|
+
FLAG_MEMO,
|
|
12
|
+
FLAG_NOOP,
|
|
10
13
|
} from "./constants.js"
|
|
11
14
|
import { commitDeletion, commitWork, createDom, hydrateDom } from "./dom.js"
|
|
12
15
|
import { __DEV__ } from "./env.js"
|
|
@@ -16,10 +19,8 @@ import { hydrationStack } from "./hydration.js"
|
|
|
16
19
|
import { assertValidElementProps } from "./props.js"
|
|
17
20
|
import { reconcileChildren } from "./reconciler.js"
|
|
18
21
|
import {
|
|
19
|
-
willMemoBlockUpdate,
|
|
20
22
|
latest,
|
|
21
23
|
traverseApply,
|
|
22
|
-
vNodeContains,
|
|
23
24
|
isExoticType,
|
|
24
25
|
getVNodeAppContext,
|
|
25
26
|
} from "./utils.js"
|
|
@@ -28,9 +29,7 @@ import type { AppContext } from "./appContext"
|
|
|
28
29
|
type VNode = Kiru.VNode
|
|
29
30
|
|
|
30
31
|
let appCtx: AppContext | null
|
|
31
|
-
let nextUnitOfWork: VNode | null = null
|
|
32
32
|
let treesInProgress: VNode[] = []
|
|
33
|
-
let currentTreeIndex = 0
|
|
34
33
|
let isRunningOrQueued = false
|
|
35
34
|
let nextIdleEffects: (() => void)[] = []
|
|
36
35
|
let deletions: VNode[] = []
|
|
@@ -38,7 +37,6 @@ let isImmediateEffectsMode = false
|
|
|
38
37
|
let immediateEffectDirtiedRender = false
|
|
39
38
|
let isRenderDirtied = false
|
|
40
39
|
let consecutiveDirtyCount = 0
|
|
41
|
-
let pendingContextChanges = new Set<ContextProviderNode<any>>()
|
|
42
40
|
let preEffects: Array<Function> = []
|
|
43
41
|
let postEffects: Array<Function> = []
|
|
44
42
|
let animationFrameHandle = -1
|
|
@@ -105,91 +103,14 @@ function queueUpdate(vNode: VNode) {
|
|
|
105
103
|
return
|
|
106
104
|
}
|
|
107
105
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return
|
|
111
|
-
}
|
|
106
|
+
if (vNode.flags & (FLAG_DIRTY | FLAG_DELETION)) return
|
|
107
|
+
vNode.flags |= FLAG_DIRTY
|
|
112
108
|
|
|
113
|
-
if (
|
|
109
|
+
if (!treesInProgress.length) {
|
|
114
110
|
treesInProgress.push(vNode)
|
|
115
|
-
nextUnitOfWork = vNode
|
|
116
111
|
return queueBeginWork()
|
|
117
112
|
}
|
|
118
113
|
|
|
119
|
-
for (let i = 0; i < treesInProgress.length; i++) {
|
|
120
|
-
const tree = treesInProgress[i]
|
|
121
|
-
if (tree !== vNode) continue
|
|
122
|
-
if (i < currentTreeIndex) {
|
|
123
|
-
// It was already processed; requeue it to the end
|
|
124
|
-
currentTreeIndex--
|
|
125
|
-
treesInProgress.splice(i, 1)
|
|
126
|
-
treesInProgress.push(tree)
|
|
127
|
-
}
|
|
128
|
-
return
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Check if this node is a descendant of any trees already queued
|
|
132
|
-
for (let i = 0; i < treesInProgress.length; i++) {
|
|
133
|
-
const tree = treesInProgress[i]
|
|
134
|
-
if (!vNodeContains(tree, vNode)) continue
|
|
135
|
-
|
|
136
|
-
if (i === currentTreeIndex) {
|
|
137
|
-
// It's a child of the currently worked-on tree
|
|
138
|
-
// If it's deeper within the same tree, we can skip
|
|
139
|
-
if (vNodeContains(nextUnitOfWork, vNode)) return
|
|
140
|
-
// If it's not in the current work subtree, move back up to it
|
|
141
|
-
nextUnitOfWork = vNode
|
|
142
|
-
} else if (i < currentTreeIndex) {
|
|
143
|
-
// It's a descendant of an already processed tree; treat as a new update
|
|
144
|
-
treesInProgress.push(vNode)
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Check if this node contains any of the currently queued trees
|
|
151
|
-
let didReplaceTree = false
|
|
152
|
-
let shouldQueueAtEnd = false
|
|
153
|
-
for (let i = 0; i < treesInProgress.length; ) {
|
|
154
|
-
const tree = treesInProgress[i]
|
|
155
|
-
if (!vNodeContains(vNode, tree)) {
|
|
156
|
-
i++
|
|
157
|
-
continue
|
|
158
|
-
}
|
|
159
|
-
// This node contains another update root, replace it
|
|
160
|
-
|
|
161
|
-
if (i === currentTreeIndex) {
|
|
162
|
-
if (!didReplaceTree) {
|
|
163
|
-
treesInProgress.splice(i, 1, vNode)
|
|
164
|
-
nextUnitOfWork = vNode
|
|
165
|
-
didReplaceTree = true
|
|
166
|
-
i++ // advance past replaced node
|
|
167
|
-
} else {
|
|
168
|
-
treesInProgress.splice(i, 1)
|
|
169
|
-
// no increment
|
|
170
|
-
}
|
|
171
|
-
} else if (i < currentTreeIndex) {
|
|
172
|
-
currentTreeIndex--
|
|
173
|
-
treesInProgress.splice(i, 1)
|
|
174
|
-
if (!didReplaceTree) {
|
|
175
|
-
shouldQueueAtEnd = true
|
|
176
|
-
didReplaceTree = true
|
|
177
|
-
}
|
|
178
|
-
// no increment
|
|
179
|
-
} else {
|
|
180
|
-
// i > currentTreeIndex
|
|
181
|
-
treesInProgress.splice(i, 1)
|
|
182
|
-
if (!didReplaceTree) {
|
|
183
|
-
shouldQueueAtEnd = true
|
|
184
|
-
didReplaceTree = true
|
|
185
|
-
}
|
|
186
|
-
// no increment
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
if (!shouldQueueAtEnd && didReplaceTree) {
|
|
190
|
-
return
|
|
191
|
-
}
|
|
192
|
-
// If it doesn't overlap with any queued tree, queue as new independent update root
|
|
193
114
|
treesInProgress.push(vNode)
|
|
194
115
|
}
|
|
195
116
|
|
|
@@ -198,9 +119,13 @@ function queueDelete(vNode: VNode) {
|
|
|
198
119
|
deletions.push(vNode)
|
|
199
120
|
}
|
|
200
121
|
|
|
122
|
+
const depthSort = (a: VNode, b: VNode) => b.depth - a.depth
|
|
123
|
+
|
|
124
|
+
let currentWorkRoot: VNode | null = null
|
|
125
|
+
|
|
201
126
|
function doWork(): void {
|
|
202
127
|
if (__DEV__) {
|
|
203
|
-
const n =
|
|
128
|
+
const n = deletions[0] ?? treesInProgress[0]
|
|
204
129
|
if (n) {
|
|
205
130
|
appCtx = getVNodeAppContext(n)!
|
|
206
131
|
window.__kiru?.profilingContext?.beginTick(appCtx)
|
|
@@ -209,21 +134,29 @@ function doWork(): void {
|
|
|
209
134
|
}
|
|
210
135
|
}
|
|
211
136
|
|
|
212
|
-
|
|
213
|
-
nextUnitOfWork =
|
|
214
|
-
performUnitOfWork(nextUnitOfWork) ??
|
|
215
|
-
treesInProgress[++currentTreeIndex] ??
|
|
216
|
-
queueBlockedContextDependencyRoots()
|
|
217
|
-
}
|
|
137
|
+
let len = 1
|
|
218
138
|
|
|
219
|
-
while (
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
139
|
+
while (treesInProgress.length) {
|
|
140
|
+
if (treesInProgress.length > len) {
|
|
141
|
+
treesInProgress.sort(depthSort)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
currentWorkRoot = treesInProgress.shift()!
|
|
145
|
+
len = treesInProgress.length
|
|
146
|
+
|
|
147
|
+
const flags = currentWorkRoot.flags
|
|
148
|
+
if (flags & FLAG_DELETION) continue
|
|
149
|
+
if (flags & FLAG_DIRTY) {
|
|
150
|
+
let n: VNode | void = currentWorkRoot
|
|
151
|
+
while ((n = performUnitOfWork(n))) {}
|
|
152
|
+
|
|
153
|
+
while (deletions.length) {
|
|
154
|
+
commitDeletion(deletions.pop()!)
|
|
155
|
+
}
|
|
156
|
+
commitWork(currentWorkRoot)
|
|
157
|
+
|
|
158
|
+
currentWorkRoot.flags &= ~FLAG_DIRTY
|
|
159
|
+
}
|
|
227
160
|
}
|
|
228
161
|
|
|
229
162
|
isImmediateEffectsMode = true
|
|
@@ -252,39 +185,6 @@ function doWork(): void {
|
|
|
252
185
|
}
|
|
253
186
|
}
|
|
254
187
|
|
|
255
|
-
function queueBlockedContextDependencyRoots(): VNode | null {
|
|
256
|
-
if (pendingContextChanges.size === 0) return null
|
|
257
|
-
|
|
258
|
-
// TODO: it's possible that a 'job' created by this process is
|
|
259
|
-
// blocked by a parent memo after a queueUpdate -> replaceTree action.
|
|
260
|
-
// To prevent this, we might need to add these to a distinct queue.
|
|
261
|
-
const jobRoots: VNode[] = []
|
|
262
|
-
pendingContextChanges.forEach((provider) => {
|
|
263
|
-
provider.props.dependents.forEach((dep) => {
|
|
264
|
-
if (!willMemoBlockUpdate(provider, dep)) return
|
|
265
|
-
for (let i = 0; i < jobRoots.length; i++) {
|
|
266
|
-
const root = jobRoots[i]
|
|
267
|
-
if (vNodeContains(root, dep)) {
|
|
268
|
-
if (willMemoBlockUpdate(root, dep)) {
|
|
269
|
-
// root is a parent of dep and there's a memo between them, prevent consolidation and queue as new root
|
|
270
|
-
break
|
|
271
|
-
}
|
|
272
|
-
return
|
|
273
|
-
}
|
|
274
|
-
if (vNodeContains(dep, root)) {
|
|
275
|
-
jobRoots[i] = dep
|
|
276
|
-
return
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
jobRoots.push(dep)
|
|
280
|
-
})
|
|
281
|
-
})
|
|
282
|
-
|
|
283
|
-
pendingContextChanges.clear()
|
|
284
|
-
treesInProgress.push(...jobRoots)
|
|
285
|
-
return jobRoots[0] ?? null
|
|
286
|
-
}
|
|
287
|
-
|
|
288
188
|
function performUnitOfWork(vNode: VNode): VNode | void {
|
|
289
189
|
let renderChild = true
|
|
290
190
|
try {
|
|
@@ -292,15 +192,15 @@ function performUnitOfWork(vNode: VNode): VNode | void {
|
|
|
292
192
|
if (typeof vNode.type === "string") {
|
|
293
193
|
updateHostComponent(vNode as DomVNode)
|
|
294
194
|
} else if (isExoticType(vNode.type)) {
|
|
295
|
-
if (vNode
|
|
195
|
+
if (vNode?.type === $CONTEXT_PROVIDER) {
|
|
296
196
|
const asProvider = vNode as ContextProviderNode<any>
|
|
297
|
-
const {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
) {
|
|
303
|
-
|
|
197
|
+
const {
|
|
198
|
+
props: { dependents, value },
|
|
199
|
+
prev,
|
|
200
|
+
} = asProvider
|
|
201
|
+
|
|
202
|
+
if (dependents.size && prev && prev.props.value !== value) {
|
|
203
|
+
dependents.forEach(queueUpdate)
|
|
304
204
|
}
|
|
305
205
|
}
|
|
306
206
|
vNode.child = reconcileChildren(vNode, props.children)
|
|
@@ -350,7 +250,7 @@ function performUnitOfWork(vNode: VNode): VNode | void {
|
|
|
350
250
|
nextNode.effects = undefined
|
|
351
251
|
}
|
|
352
252
|
|
|
353
|
-
if (nextNode ===
|
|
253
|
+
if (nextNode === currentWorkRoot) return
|
|
354
254
|
if (nextNode.sibling) {
|
|
355
255
|
return nextNode.sibling
|
|
356
256
|
}
|
|
@@ -363,22 +263,25 @@ function performUnitOfWork(vNode: VNode): VNode | void {
|
|
|
363
263
|
}
|
|
364
264
|
|
|
365
265
|
function updateFunctionComponent(vNode: FunctionVNode) {
|
|
366
|
-
const { type, props, subs, prev,
|
|
367
|
-
if (
|
|
266
|
+
const { type, props, subs, prev, flags } = vNode
|
|
267
|
+
if (flags & FLAG_MEMO) {
|
|
368
268
|
vNode.memoizedProps = props
|
|
369
269
|
if (
|
|
370
270
|
prev?.memoizedProps &&
|
|
371
271
|
vNode.arePropsEqual!(prev.memoizedProps, props) &&
|
|
372
272
|
!vNode.hmrUpdated
|
|
373
273
|
) {
|
|
274
|
+
vNode.flags |= FLAG_NOOP
|
|
374
275
|
return false
|
|
375
276
|
}
|
|
277
|
+
vNode.flags &= ~FLAG_NOOP
|
|
376
278
|
}
|
|
377
279
|
try {
|
|
378
280
|
node.current = vNode
|
|
379
281
|
let newChild
|
|
380
282
|
let renderTryCount = 0
|
|
381
283
|
do {
|
|
284
|
+
vNode.flags &= ~FLAG_DIRTY
|
|
382
285
|
isRenderDirtied = false
|
|
383
286
|
hookIndex.current = 0
|
|
384
287
|
|
package/src/signals/base.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
import { latest, safeStringify, sideEffectsEnabled } from "../utils.js"
|
|
1
2
|
import { $HMR_ACCEPT, $SIGNAL } from "../constants.js"
|
|
2
3
|
import { __DEV__ } from "../env.js"
|
|
3
|
-
import type { HMRAccept } from "../hmr.js"
|
|
4
|
-
import { latest, safeStringify, sideEffectsEnabled } from "../utils.js"
|
|
5
|
-
import { tracking, signalSubsMap } from "./globals.js"
|
|
6
|
-
import { type SignalSubscriber, ReadonlySignal } from "./types.js"
|
|
7
4
|
import { node } from "../globals.js"
|
|
8
5
|
import { useHook } from "../hooks/utils.js"
|
|
9
6
|
import { generateRandomID } from "../generateId.js"
|
|
10
7
|
import { requestUpdate } from "../scheduler.js"
|
|
8
|
+
import { tracking, signalSubsMap } from "./globals.js"
|
|
9
|
+
import type { SignalSubscriber, ReadonlySignal } from "./types.js"
|
|
10
|
+
import type { HMRAccept } from "../hmr.js"
|
|
11
11
|
|
|
12
12
|
export class Signal<T> {
|
|
13
13
|
[$SIGNAL] = true;
|
package/src/signals/computed.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { __DEV__ } from "../env.js"
|
|
2
|
-
import { Signal } from "./index.js"
|
|
3
|
-
import { effectQueue, signalSubsMap } from "./globals.js"
|
|
4
2
|
import { $HMR_ACCEPT } from "../constants.js"
|
|
5
|
-
import type { HMRAccept } from "../hmr.js"
|
|
6
3
|
import { useHook } from "../hooks/utils.js"
|
|
7
|
-
import { executeWithTracking } from "./effect.js"
|
|
8
4
|
import { latest } from "../utils.js"
|
|
5
|
+
import { effectQueue, signalSubsMap } from "./globals.js"
|
|
6
|
+
import { executeWithTracking } from "./effect.js"
|
|
7
|
+
import { Signal } from "./base.js"
|
|
8
|
+
import type { HMRAccept } from "../hmr.js"
|
|
9
9
|
|
|
10
10
|
export class ComputedSignal<T> extends Signal<T> {
|
|
11
11
|
protected $getter: (prev?: T) => T
|
package/src/signals/effect.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { node } from "../globals.js"
|
|
2
2
|
import { sideEffectsEnabled } from "../utils.js"
|
|
3
3
|
import { tracking, effectQueue } from "./globals.js"
|
|
4
|
-
import
|
|
4
|
+
import { tick } from "./utils.js"
|
|
5
|
+
import type { Signal } from "./base.js"
|
|
5
6
|
import type { SignalValues } from "./types.js"
|
|
6
7
|
|
|
7
8
|
type TrackedExecutionContext<T, Deps extends readonly Signal<unknown>[]> = {
|
|
@@ -42,8 +43,8 @@ export function executeWithTracking<T, Deps extends readonly Signal<unknown>[]>(
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
const effect = () => {
|
|
45
|
-
if (!effectQueue.
|
|
46
|
-
queueMicrotask(
|
|
46
|
+
if (!effectQueue.size) {
|
|
47
|
+
queueMicrotask(tick)
|
|
47
48
|
}
|
|
48
49
|
effectQueue.set(id, onDepChanged)
|
|
49
50
|
}
|
package/src/signals/globals.ts
CHANGED
package/src/signals/jsx.ts
CHANGED
package/src/signals/types.ts
CHANGED
package/src/signals/utils.ts
CHANGED
package/src/ssr/server.ts
CHANGED
|
@@ -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/base.js"
|
|
11
11
|
import { $HYDRATION_BOUNDARY, voidElements } from "../constants.js"
|
|
12
12
|
import { assertValidElementProps } from "../props.js"
|
|
13
13
|
import { HYDRATION_BOUNDARY_MARKER } from "./hydrationBoundary.js"
|
package/src/swr.ts
CHANGED
package/src/types.ts
CHANGED
package/src/utils.ts
CHANGED
|
@@ -5,12 +5,11 @@ import {
|
|
|
5
5
|
$HYDRATION_BOUNDARY,
|
|
6
6
|
booleanAttributes,
|
|
7
7
|
FLAG_DELETION,
|
|
8
|
-
FLAG_HAS_MEMO_ANCESTOR,
|
|
9
8
|
FLAG_PLACEMENT,
|
|
10
9
|
FLAG_UPDATE,
|
|
11
10
|
REGEX_UNIT,
|
|
12
11
|
} from "./constants.js"
|
|
13
|
-
import { unwrap } from "./signals/
|
|
12
|
+
import { unwrap } from "./signals/utils.js"
|
|
14
13
|
import { __DEV__ } from "./env.js"
|
|
15
14
|
import type { AppContext } from "./appContext"
|
|
16
15
|
|
|
@@ -24,12 +23,10 @@ export {
|
|
|
24
23
|
isExoticType,
|
|
25
24
|
isVNodeDeleted,
|
|
26
25
|
vNodeContains,
|
|
27
|
-
willMemoBlockUpdate,
|
|
28
26
|
getCurrentVNode,
|
|
29
27
|
getVNodeAppContext,
|
|
30
28
|
commitSnapshot,
|
|
31
29
|
traverseApply,
|
|
32
|
-
postOrderApply,
|
|
33
30
|
findParent,
|
|
34
31
|
propToHtmlAttr,
|
|
35
32
|
propValueToHtmlAttrValue,
|
|
@@ -157,25 +154,6 @@ function vNodeContains(haystack: VNode, needle: VNode): boolean {
|
|
|
157
154
|
return false
|
|
158
155
|
}
|
|
159
156
|
|
|
160
|
-
function willMemoBlockUpdate(root: VNode, target: VNode): boolean {
|
|
161
|
-
let node: VNode | null = target
|
|
162
|
-
|
|
163
|
-
while (node && node !== root && node.flags & FLAG_HAS_MEMO_ANCESTOR) {
|
|
164
|
-
const parent = node.parent
|
|
165
|
-
if (
|
|
166
|
-
parent?.isMemoized &&
|
|
167
|
-
parent.prev?.memoizedProps &&
|
|
168
|
-
parent.arePropsEqual!(parent.prev.memoizedProps, parent.props)
|
|
169
|
-
) {
|
|
170
|
-
return true
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
node = node.parent
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return false
|
|
177
|
-
}
|
|
178
|
-
|
|
179
157
|
function traverseApply(vNode: VNode, func: (node: VNode) => void): void {
|
|
180
158
|
let applyToSiblings = false
|
|
181
159
|
const nodes: VNode[] = [vNode]
|
|
@@ -188,49 +166,6 @@ function traverseApply(vNode: VNode, func: (node: VNode) => void): void {
|
|
|
188
166
|
while (nodes.length) apply(nodes.shift()!)
|
|
189
167
|
}
|
|
190
168
|
|
|
191
|
-
function postOrderApply(
|
|
192
|
-
tree: VNode,
|
|
193
|
-
callbacks: {
|
|
194
|
-
/** called upon traversing to the next parent, and on the root */
|
|
195
|
-
onAscent: (vNode: VNode) => void
|
|
196
|
-
/** called before traversing to the next parent */
|
|
197
|
-
onBeforeAscent?: (vNode: VNode) => void
|
|
198
|
-
/** called before traversing to the next child */
|
|
199
|
-
onDescent?: (vNode: VNode) => void
|
|
200
|
-
}
|
|
201
|
-
): void {
|
|
202
|
-
const root = tree
|
|
203
|
-
const rootChild = root.child
|
|
204
|
-
if (!rootChild) {
|
|
205
|
-
callbacks.onAscent(root)
|
|
206
|
-
return
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
callbacks.onDescent?.(root)
|
|
210
|
-
let branch = rootChild
|
|
211
|
-
while (branch) {
|
|
212
|
-
let c = branch
|
|
213
|
-
while (c) {
|
|
214
|
-
if (!c.child) break
|
|
215
|
-
callbacks.onDescent?.(c)
|
|
216
|
-
c = c.child
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
while (c && c !== root) {
|
|
220
|
-
callbacks.onAscent(c)
|
|
221
|
-
if (c.sibling) {
|
|
222
|
-
branch = c.sibling
|
|
223
|
-
break
|
|
224
|
-
}
|
|
225
|
-
callbacks.onBeforeAscent?.(c)
|
|
226
|
-
c = c.parent!
|
|
227
|
-
}
|
|
228
|
-
if (c === root) break
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
callbacks.onAscent(root)
|
|
232
|
-
}
|
|
233
|
-
|
|
234
169
|
function findParent(vNode: Kiru.VNode, predicate: (n: Kiru.VNode) => boolean) {
|
|
235
170
|
let n: Kiru.VNode | null = vNode.parent
|
|
236
171
|
while (n) {
|