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/scheduler.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
$CONTEXT_PROVIDER,
|
|
8
8
|
CONSECUTIVE_DIRTY_LIMIT,
|
|
9
9
|
FLAG_DELETION,
|
|
10
|
+
FLAG_MEMO,
|
|
10
11
|
} from "./constants.js"
|
|
11
12
|
import { commitDeletion, commitWork, createDom, hydrateDom } from "./dom.js"
|
|
12
13
|
import { __DEV__ } from "./env.js"
|
|
@@ -31,7 +32,7 @@ let appCtx: AppContext | null
|
|
|
31
32
|
let nextUnitOfWork: VNode | null = null
|
|
32
33
|
let treesInProgress: VNode[] = []
|
|
33
34
|
let currentTreeIndex = 0
|
|
34
|
-
let
|
|
35
|
+
let isRunningOrQueued = false
|
|
35
36
|
let nextIdleEffects: (() => void)[] = []
|
|
36
37
|
let deletions: VNode[] = []
|
|
37
38
|
let isImmediateEffectsMode = false
|
|
@@ -41,20 +42,27 @@ let consecutiveDirtyCount = 0
|
|
|
41
42
|
let pendingContextChanges = new Set<ContextProviderNode<any>>()
|
|
42
43
|
let preEffects: Array<Function> = []
|
|
43
44
|
let postEffects: Array<Function> = []
|
|
45
|
+
let animationFrameHandle = -1
|
|
44
46
|
|
|
45
47
|
/**
|
|
46
|
-
* Runs a function after any existing work has been completed,
|
|
48
|
+
* Runs a function after any existing work has been completed,
|
|
49
|
+
* or immediately if the scheduler is already idle.
|
|
47
50
|
*/
|
|
48
|
-
export function nextIdle(fn: () => void
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
export function nextIdle(fn: () => void) {
|
|
52
|
+
if (isRunningOrQueued) {
|
|
53
|
+
nextIdleEffects.push(fn)
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
fn()
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
/**
|
|
54
60
|
* Syncronously flushes any pending work.
|
|
55
61
|
*/
|
|
56
62
|
export function flushSync() {
|
|
57
|
-
|
|
63
|
+
if (!isRunningOrQueued) return
|
|
64
|
+
window.cancelAnimationFrame(animationFrameHandle)
|
|
65
|
+
doWork()
|
|
58
66
|
}
|
|
59
67
|
|
|
60
68
|
/**
|
|
@@ -65,33 +73,22 @@ export function requestUpdate(vNode: VNode): void {
|
|
|
65
73
|
if (renderMode.current === "hydrate") {
|
|
66
74
|
return nextIdle(() => {
|
|
67
75
|
vNode.flags & FLAG_DELETION || queueUpdate(vNode)
|
|
68
|
-
}
|
|
76
|
+
})
|
|
69
77
|
}
|
|
70
78
|
queueUpdate(vNode)
|
|
71
79
|
}
|
|
72
80
|
|
|
73
|
-
|
|
74
|
-
if (
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
vNode.flags & FLAG_DELETION || queueDelete(vNode)
|
|
78
|
-
}, false)
|
|
79
|
-
}
|
|
80
|
-
queueDelete(vNode)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function queueWorkLoop() {
|
|
84
|
-
queueMicrotask(workLoop)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function wake() {
|
|
88
|
-
if (isRunning) return
|
|
89
|
-
isRunning = true
|
|
90
|
-
queueWorkLoop()
|
|
81
|
+
function queueBeginWork() {
|
|
82
|
+
if (isRunningOrQueued) return
|
|
83
|
+
isRunningOrQueued = true
|
|
84
|
+
animationFrameHandle = window.requestAnimationFrame(doWork)
|
|
91
85
|
}
|
|
92
86
|
|
|
93
|
-
function
|
|
94
|
-
|
|
87
|
+
function onWorkFinished() {
|
|
88
|
+
isRunningOrQueued = false
|
|
89
|
+
while (nextIdleEffects.length) {
|
|
90
|
+
nextIdleEffects.shift()!()
|
|
91
|
+
}
|
|
95
92
|
}
|
|
96
93
|
|
|
97
94
|
function queueUpdate(vNode: VNode) {
|
|
@@ -117,7 +114,7 @@ function queueUpdate(vNode: VNode) {
|
|
|
117
114
|
if (nextUnitOfWork === null) {
|
|
118
115
|
treesInProgress.push(vNode)
|
|
119
116
|
nextUnitOfWork = vNode
|
|
120
|
-
return
|
|
117
|
+
return queueBeginWork()
|
|
121
118
|
}
|
|
122
119
|
|
|
123
120
|
for (let i = 0; i < treesInProgress.length; i++) {
|
|
@@ -202,7 +199,7 @@ function queueDelete(vNode: VNode) {
|
|
|
202
199
|
deletions.push(vNode)
|
|
203
200
|
}
|
|
204
201
|
|
|
205
|
-
function
|
|
202
|
+
function doWork(): void {
|
|
206
203
|
if (__DEV__) {
|
|
207
204
|
const n = nextUnitOfWork ?? deletions[0] ?? treesInProgress[0]
|
|
208
205
|
if (n) {
|
|
@@ -220,55 +217,40 @@ function workLoop(): void {
|
|
|
220
217
|
queueBlockedContextDependencyRoots()
|
|
221
218
|
}
|
|
222
219
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
isImmediateEffectsMode = true
|
|
235
|
-
flushEffects(preEffects)
|
|
236
|
-
isImmediateEffectsMode = false
|
|
220
|
+
while (deletions.length) {
|
|
221
|
+
commitDeletion(deletions.shift()!)
|
|
222
|
+
}
|
|
223
|
+
const workRoots = [...treesInProgress]
|
|
224
|
+
treesInProgress.length = 0
|
|
225
|
+
currentTreeIndex = 0
|
|
226
|
+
for (const root of workRoots) {
|
|
227
|
+
commitWork(root)
|
|
228
|
+
}
|
|
237
229
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
immediateEffectDirtiedRender = false
|
|
242
|
-
consecutiveDirtyCount++
|
|
243
|
-
if (__DEV__) {
|
|
244
|
-
window.__kiru?.profilingContext?.endTick(appCtx!)
|
|
245
|
-
window.__kiru?.profilingContext?.emit("updateDirtied", appCtx!)
|
|
246
|
-
}
|
|
247
|
-
return flushSync()
|
|
248
|
-
}
|
|
249
|
-
consecutiveDirtyCount = 0
|
|
230
|
+
isImmediateEffectsMode = true
|
|
231
|
+
flushEffects(preEffects)
|
|
232
|
+
isImmediateEffectsMode = false
|
|
250
233
|
|
|
234
|
+
if (immediateEffectDirtiedRender) {
|
|
235
|
+
checkForTooManyConsecutiveDirtyRenders()
|
|
251
236
|
flushEffects(postEffects)
|
|
237
|
+
immediateEffectDirtiedRender = false
|
|
238
|
+
consecutiveDirtyCount++
|
|
252
239
|
if (__DEV__) {
|
|
253
|
-
window.__kiru
|
|
254
|
-
window.__kiru?.profilingContext?.emit("
|
|
240
|
+
window.__kiru?.profilingContext?.endTick(appCtx!)
|
|
241
|
+
window.__kiru?.profilingContext?.emit("updateDirtied", appCtx!)
|
|
255
242
|
}
|
|
243
|
+
return flushSync()
|
|
256
244
|
}
|
|
245
|
+
consecutiveDirtyCount = 0
|
|
257
246
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
if (appCtx) {
|
|
265
|
-
window.__kiru?.profilingContext?.endTick(appCtx)
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
return
|
|
247
|
+
onWorkFinished()
|
|
248
|
+
flushEffects(postEffects)
|
|
249
|
+
if (__DEV__) {
|
|
250
|
+
window.__kiru!.emit("update", appCtx!)
|
|
251
|
+
window.__kiru?.profilingContext?.emit("update", appCtx!)
|
|
252
|
+
window.__kiru?.profilingContext?.endTick(appCtx!)
|
|
269
253
|
}
|
|
270
|
-
|
|
271
|
-
queueWorkLoop()
|
|
272
254
|
}
|
|
273
255
|
|
|
274
256
|
function queueBlockedContextDependencyRoots(): VNode | null {
|
|
@@ -382,8 +364,8 @@ function performUnitOfWork(vNode: VNode): VNode | void {
|
|
|
382
364
|
}
|
|
383
365
|
|
|
384
366
|
function updateFunctionComponent(vNode: FunctionVNode) {
|
|
385
|
-
const { type, props, subs, prev,
|
|
386
|
-
if (
|
|
367
|
+
const { type, props, subs, prev, flags } = vNode
|
|
368
|
+
if (flags & FLAG_MEMO) {
|
|
387
369
|
vNode.memoizedProps = props
|
|
388
370
|
if (
|
|
389
371
|
prev?.memoizedProps &&
|
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/client.ts
CHANGED
|
@@ -3,27 +3,21 @@ import { hydrationStack } from "../hydration.js"
|
|
|
3
3
|
import { renderMode } from "../globals.js"
|
|
4
4
|
import { mount } from "../index.js"
|
|
5
5
|
|
|
6
|
-
export function hydrate
|
|
7
|
-
|
|
8
|
-
container: AppContextOptions,
|
|
9
|
-
appProps?: T
|
|
10
|
-
): Promise<AppContext<T>>
|
|
11
|
-
|
|
12
|
-
export function hydrate<T extends Record<string, unknown>>(
|
|
13
|
-
appFunc: (props: T) => JSX.Element,
|
|
6
|
+
export function hydrate(
|
|
7
|
+
children: JSX.Element,
|
|
14
8
|
container: HTMLElement,
|
|
15
|
-
|
|
16
|
-
):
|
|
17
|
-
|
|
18
|
-
export function hydrate<T extends Record<string, unknown>>(
|
|
19
|
-
appFunc: (props: T) => JSX.Element,
|
|
20
|
-
optionsOrRoot: HTMLElement | AppContextOptions,
|
|
21
|
-
appProps = {} as T
|
|
22
|
-
) {
|
|
9
|
+
options?: AppContextOptions
|
|
10
|
+
): AppContext {
|
|
23
11
|
hydrationStack.clear()
|
|
12
|
+
|
|
24
13
|
const prevRenderMode = renderMode.current
|
|
25
14
|
renderMode.current = "hydrate"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
15
|
+
hydrationStack.captureEvents(container)
|
|
16
|
+
|
|
17
|
+
const app = mount(children, container, options)
|
|
18
|
+
|
|
19
|
+
renderMode.current = prevRenderMode
|
|
20
|
+
hydrationStack.releaseEvents(container)
|
|
21
|
+
|
|
22
|
+
return app
|
|
29
23
|
}
|
package/src/ssr/server.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Readable } from "node:stream"
|
|
2
2
|
import { Fragment } from "../element.js"
|
|
3
|
-
import { AppContext, createAppContext } from "../appContext.js"
|
|
4
3
|
import { renderMode, node } from "../globals.js"
|
|
5
4
|
import {
|
|
6
5
|
isVNode,
|
|
@@ -14,30 +13,21 @@ import { assertValidElementProps } from "../props.js"
|
|
|
14
13
|
import { HYDRATION_BOUNDARY_MARKER } from "./hydrationBoundary.js"
|
|
15
14
|
import { __DEV__ } from "../env.js"
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
stream: Readable
|
|
19
|
-
ctx: AppContext
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function renderToReadableStream<T extends Record<string, unknown>>(
|
|
23
|
-
appFunc: (props: T) => JSX.Element,
|
|
24
|
-
appProps = {} as T
|
|
25
|
-
): Readable {
|
|
16
|
+
export function renderToReadableStream(element: JSX.Element): Readable {
|
|
26
17
|
const prev = renderMode.current
|
|
27
18
|
renderMode.current = "stream"
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
state.stream.push(null)
|
|
19
|
+
const stream = new Readable()
|
|
20
|
+
const rootNode = Fragment({ children: element })
|
|
21
|
+
|
|
22
|
+
renderToStream_internal(stream, rootNode, null, 0)
|
|
23
|
+
stream.push(null)
|
|
34
24
|
renderMode.current = prev
|
|
35
25
|
|
|
36
|
-
return
|
|
26
|
+
return stream
|
|
37
27
|
}
|
|
38
28
|
|
|
39
29
|
function renderToStream_internal(
|
|
40
|
-
|
|
30
|
+
stream: Readable,
|
|
41
31
|
el: unknown,
|
|
42
32
|
parent: Kiru.VNode | null,
|
|
43
33
|
idx: number
|
|
@@ -46,23 +36,23 @@ function renderToStream_internal(
|
|
|
46
36
|
if (el === undefined) return
|
|
47
37
|
if (typeof el === "boolean") return
|
|
48
38
|
if (typeof el === "string") {
|
|
49
|
-
|
|
39
|
+
stream.push(encodeHtmlEntities(el))
|
|
50
40
|
return
|
|
51
41
|
}
|
|
52
42
|
if (typeof el === "number" || typeof el === "bigint") {
|
|
53
|
-
|
|
43
|
+
stream.push(el.toString())
|
|
54
44
|
return
|
|
55
45
|
}
|
|
56
46
|
if (el instanceof Array) {
|
|
57
|
-
el.forEach((c, i) => renderToStream_internal(
|
|
47
|
+
el.forEach((c, i) => renderToStream_internal(stream, c, parent, i))
|
|
58
48
|
return
|
|
59
49
|
}
|
|
60
50
|
if (Signal.isSignal(el)) {
|
|
61
|
-
|
|
51
|
+
stream.push(String(el.peek()))
|
|
62
52
|
return
|
|
63
53
|
}
|
|
64
54
|
if (!isVNode(el)) {
|
|
65
|
-
|
|
55
|
+
stream.push(String(el))
|
|
66
56
|
return
|
|
67
57
|
}
|
|
68
58
|
el.parent = parent
|
|
@@ -72,35 +62,35 @@ function renderToStream_internal(
|
|
|
72
62
|
const children = props.children
|
|
73
63
|
const type = el.type
|
|
74
64
|
if (type === "#text") {
|
|
75
|
-
|
|
65
|
+
stream.push(encodeHtmlEntities(props.nodeValue ?? ""))
|
|
76
66
|
return
|
|
77
67
|
}
|
|
78
68
|
if (isExoticType(type)) {
|
|
79
69
|
if (type === $HYDRATION_BOUNDARY) {
|
|
80
|
-
|
|
81
|
-
renderToStream_internal(
|
|
82
|
-
|
|
70
|
+
stream.push(`<!--${HYDRATION_BOUNDARY_MARKER}-->`)
|
|
71
|
+
renderToStream_internal(stream, children, el, idx)
|
|
72
|
+
stream.push(`<!--/${HYDRATION_BOUNDARY_MARKER}-->`)
|
|
83
73
|
return
|
|
84
74
|
}
|
|
85
|
-
return renderToStream_internal(
|
|
75
|
+
return renderToStream_internal(stream, children, el, idx)
|
|
86
76
|
}
|
|
87
77
|
|
|
88
78
|
if (typeof type !== "string") {
|
|
89
79
|
node.current = el
|
|
90
80
|
const res = type(props)
|
|
91
81
|
node.current = null
|
|
92
|
-
return renderToStream_internal(
|
|
82
|
+
return renderToStream_internal(stream, res, parent, idx)
|
|
93
83
|
}
|
|
94
84
|
|
|
95
85
|
if (__DEV__) {
|
|
96
86
|
assertValidElementProps(el)
|
|
97
87
|
}
|
|
98
88
|
const attrs = propsToElementAttributes(props)
|
|
99
|
-
|
|
89
|
+
stream.push(`<${type}${attrs.length ? ` ${attrs}` : ""}>`)
|
|
100
90
|
|
|
101
91
|
if (!voidElements.has(type)) {
|
|
102
92
|
if ("innerHTML" in props) {
|
|
103
|
-
|
|
93
|
+
stream.push(
|
|
104
94
|
String(
|
|
105
95
|
Signal.isSignal(props.innerHTML)
|
|
106
96
|
? props.innerHTML.peek()
|
|
@@ -109,12 +99,12 @@ function renderToStream_internal(
|
|
|
109
99
|
)
|
|
110
100
|
} else {
|
|
111
101
|
if (Array.isArray(children)) {
|
|
112
|
-
children.forEach((c, i) => renderToStream_internal(
|
|
102
|
+
children.forEach((c, i) => renderToStream_internal(stream, c, el, i))
|
|
113
103
|
} else {
|
|
114
|
-
renderToStream_internal(
|
|
104
|
+
renderToStream_internal(stream, children, el, 0)
|
|
115
105
|
}
|
|
116
106
|
}
|
|
117
107
|
|
|
118
|
-
|
|
108
|
+
stream.push(`</${type}>`)
|
|
119
109
|
}
|
|
120
110
|
}
|
package/src/types.ts
CHANGED
package/src/utils.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
FLAG_HAS_MEMO_ANCESTOR,
|
|
9
9
|
FLAG_PLACEMENT,
|
|
10
10
|
FLAG_UPDATE,
|
|
11
|
+
FLAG_MEMO,
|
|
11
12
|
REGEX_UNIT,
|
|
12
13
|
} from "./constants.js"
|
|
13
14
|
import { unwrap } from "./signals/utils.js"
|
|
@@ -162,8 +163,9 @@ function willMemoBlockUpdate(root: VNode, target: VNode): boolean {
|
|
|
162
163
|
|
|
163
164
|
while (node && node !== root && node.flags & FLAG_HAS_MEMO_ANCESTOR) {
|
|
164
165
|
const parent = node.parent
|
|
166
|
+
if (!parent) return false
|
|
165
167
|
if (
|
|
166
|
-
parent
|
|
168
|
+
parent.flags & FLAG_MEMO &&
|
|
167
169
|
parent.prev?.memoizedProps &&
|
|
168
170
|
parent.arePropsEqual!(parent.prev.memoizedProps, parent.props)
|
|
169
171
|
) {
|