kiru 0.46.0 → 0.47.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/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 +2 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -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 +10 -13
- package/dist/dom.js.map +1 -1
- package/dist/hmr.d.ts +1 -2
- 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 +0 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -20
- package/dist/index.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/renderToString.d.ts +1 -1
- package/dist/renderToString.d.ts.map +1 -1
- package/dist/renderToString.js +3 -6
- package/dist/renderToString.js.map +1 -1
- package/dist/scheduler.d.ts +11 -2
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +59 -71
- package/dist/scheduler.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 +24 -27
- 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/utils.js +1 -1
- package/package.json +1 -1
- package/src/appContext.ts +50 -117
- package/src/constants.ts +2 -0
- package/src/context.ts +0 -1
- package/src/dom.ts +10 -10
- package/src/hmr.ts +1 -3
- package/src/index.ts +0 -40
- package/src/portal.ts +22 -26
- package/src/renderToString.ts +3 -9
- package/src/scheduler.ts +59 -74
- package/src/ssr/client.ts +13 -19
- package/src/ssr/server.ts +25 -35
- package/src/swr.ts +1 -1
- package/src/utils.ts +1 -1
package/src/scheduler.ts
CHANGED
|
@@ -31,7 +31,7 @@ let appCtx: AppContext | null
|
|
|
31
31
|
let nextUnitOfWork: VNode | null = null
|
|
32
32
|
let treesInProgress: VNode[] = []
|
|
33
33
|
let currentTreeIndex = 0
|
|
34
|
-
let
|
|
34
|
+
let isRunningOrQueued = false
|
|
35
35
|
let nextIdleEffects: (() => void)[] = []
|
|
36
36
|
let deletions: VNode[] = []
|
|
37
37
|
let isImmediateEffectsMode = false
|
|
@@ -41,23 +41,34 @@ let consecutiveDirtyCount = 0
|
|
|
41
41
|
let pendingContextChanges = new Set<ContextProviderNode<any>>()
|
|
42
42
|
let preEffects: Array<Function> = []
|
|
43
43
|
let postEffects: Array<Function> = []
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
let animationFrameHandle = -1
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Runs a function after any existing work has been completed,
|
|
48
|
+
* or immediately if the scheduler is already idle.
|
|
49
|
+
*/
|
|
50
|
+
export function nextIdle(fn: () => void) {
|
|
51
|
+
if (isRunningOrQueued) {
|
|
52
|
+
nextIdleEffects.push(fn)
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
fn()
|
|
48
56
|
}
|
|
49
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Syncronously flushes any pending work.
|
|
60
|
+
*/
|
|
50
61
|
export function flushSync() {
|
|
51
|
-
|
|
62
|
+
if (!isRunningOrQueued) return
|
|
63
|
+
window.cancelAnimationFrame(animationFrameHandle)
|
|
64
|
+
doWork()
|
|
52
65
|
}
|
|
53
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Queues a node for an update. Has no effect if the node is already deleted or marked for deletion.
|
|
69
|
+
*/
|
|
54
70
|
export function requestUpdate(vNode: VNode): void {
|
|
55
71
|
if (vNode.flags & FLAG_DELETION) return
|
|
56
|
-
if (__DEV__) {
|
|
57
|
-
// if (options?.debug?.onRequestUpdate) {
|
|
58
|
-
// options.debug.onRequestUpdate(vNode)
|
|
59
|
-
// }
|
|
60
|
-
}
|
|
61
72
|
if (renderMode.current === "hydrate") {
|
|
62
73
|
return nextIdle(() => {
|
|
63
74
|
vNode.flags & FLAG_DELETION || queueUpdate(vNode)
|
|
@@ -66,28 +77,17 @@ export function requestUpdate(vNode: VNode): void {
|
|
|
66
77
|
queueUpdate(vNode)
|
|
67
78
|
}
|
|
68
79
|
|
|
69
|
-
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
vNode.flags & FLAG_DELETION || queueDelete(vNode)
|
|
74
|
-
})
|
|
75
|
-
}
|
|
76
|
-
queueDelete(vNode)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function queueWorkLoop() {
|
|
80
|
-
queueMicrotask(workLoop)
|
|
80
|
+
function queueBeginWork() {
|
|
81
|
+
if (isRunningOrQueued) return
|
|
82
|
+
isRunningOrQueued = true
|
|
83
|
+
animationFrameHandle = window.requestAnimationFrame(doWork)
|
|
81
84
|
}
|
|
82
85
|
|
|
83
|
-
function
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function sleep() {
|
|
90
|
-
isRunning = false
|
|
86
|
+
function onWorkFinished() {
|
|
87
|
+
isRunningOrQueued = false
|
|
88
|
+
while (nextIdleEffects.length) {
|
|
89
|
+
nextIdleEffects.shift()!()
|
|
90
|
+
}
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
function queueUpdate(vNode: VNode) {
|
|
@@ -113,7 +113,7 @@ function queueUpdate(vNode: VNode) {
|
|
|
113
113
|
if (nextUnitOfWork === null) {
|
|
114
114
|
treesInProgress.push(vNode)
|
|
115
115
|
nextUnitOfWork = vNode
|
|
116
|
-
return
|
|
116
|
+
return queueBeginWork()
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
for (let i = 0; i < treesInProgress.length; i++) {
|
|
@@ -198,7 +198,7 @@ function queueDelete(vNode: VNode) {
|
|
|
198
198
|
deletions.push(vNode)
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
function
|
|
201
|
+
function doWork(): void {
|
|
202
202
|
if (__DEV__) {
|
|
203
203
|
const n = nextUnitOfWork ?? deletions[0] ?? treesInProgress[0]
|
|
204
204
|
if (n) {
|
|
@@ -216,55 +216,40 @@ function workLoop(): void {
|
|
|
216
216
|
queueBlockedContextDependencyRoots()
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
isImmediateEffectsMode = true
|
|
231
|
-
flushEffects(preEffects)
|
|
232
|
-
isImmediateEffectsMode = false
|
|
219
|
+
while (deletions.length) {
|
|
220
|
+
commitDeletion(deletions.shift()!)
|
|
221
|
+
}
|
|
222
|
+
const workRoots = [...treesInProgress]
|
|
223
|
+
treesInProgress.length = 0
|
|
224
|
+
currentTreeIndex = 0
|
|
225
|
+
for (const root of workRoots) {
|
|
226
|
+
commitWork(root)
|
|
227
|
+
}
|
|
233
228
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
immediateEffectDirtiedRender = false
|
|
238
|
-
consecutiveDirtyCount++
|
|
239
|
-
if (__DEV__) {
|
|
240
|
-
window.__kiru?.profilingContext?.endTick(appCtx!)
|
|
241
|
-
window.__kiru?.profilingContext?.emit("updateDirtied", appCtx!)
|
|
242
|
-
}
|
|
243
|
-
return flushSync()
|
|
244
|
-
}
|
|
245
|
-
consecutiveDirtyCount = 0
|
|
229
|
+
isImmediateEffectsMode = true
|
|
230
|
+
flushEffects(preEffects)
|
|
231
|
+
isImmediateEffectsMode = false
|
|
246
232
|
|
|
233
|
+
if (immediateEffectDirtiedRender) {
|
|
234
|
+
checkForTooManyConsecutiveDirtyRenders()
|
|
247
235
|
flushEffects(postEffects)
|
|
236
|
+
immediateEffectDirtiedRender = false
|
|
237
|
+
consecutiveDirtyCount++
|
|
248
238
|
if (__DEV__) {
|
|
249
|
-
window.__kiru
|
|
250
|
-
window.__kiru?.profilingContext?.emit("
|
|
239
|
+
window.__kiru?.profilingContext?.endTick(appCtx!)
|
|
240
|
+
window.__kiru?.profilingContext?.emit("updateDirtied", appCtx!)
|
|
251
241
|
}
|
|
242
|
+
return flushSync()
|
|
252
243
|
}
|
|
244
|
+
consecutiveDirtyCount = 0
|
|
253
245
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
if (appCtx) {
|
|
261
|
-
window.__kiru?.profilingContext?.endTick(appCtx)
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
return
|
|
246
|
+
onWorkFinished()
|
|
247
|
+
flushEffects(postEffects)
|
|
248
|
+
if (__DEV__) {
|
|
249
|
+
window.__kiru!.emit("update", appCtx!)
|
|
250
|
+
window.__kiru?.profilingContext?.emit("update", appCtx!)
|
|
251
|
+
window.__kiru?.profilingContext?.endTick(appCtx!)
|
|
265
252
|
}
|
|
266
|
-
|
|
267
|
-
queueWorkLoop()
|
|
268
253
|
}
|
|
269
254
|
|
|
270
255
|
function queueBlockedContextDependencyRoots(): VNode | null {
|
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,
|
|
@@ -8,36 +7,27 @@ import {
|
|
|
8
7
|
propsToElementAttributes,
|
|
9
8
|
isExoticType,
|
|
10
9
|
} from "../utils.js"
|
|
11
|
-
import { Signal } from "../signals/
|
|
10
|
+
import { Signal } from "../signals/index.js"
|
|
12
11
|
import { $HYDRATION_BOUNDARY, voidElements } from "../constants.js"
|
|
13
12
|
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/swr.ts
CHANGED
package/src/utils.ts
CHANGED