kiru 0.52.3 → 0.53.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.map +1 -1
- package/dist/appContext.js +14 -11
- package/dist/appContext.js.map +1 -1
- package/dist/components/derive.d.ts +20 -0
- package/dist/components/derive.d.ts.map +1 -0
- package/dist/components/derive.js +57 -0
- package/dist/components/derive.js.map +1 -0
- package/dist/components/errorBoundary.d.ts +1 -1
- package/dist/components/errorBoundary.d.ts.map +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/index.js.map +1 -1
- package/dist/components/memo.d.ts +6 -3
- package/dist/components/memo.d.ts.map +1 -1
- package/dist/components/memo.js.map +1 -1
- package/dist/constants.d.ts +3 -3
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -3
- package/dist/constants.js.map +1 -1
- package/dist/dom.d.ts.map +1 -1
- package/dist/dom.js +69 -66
- package/dist/dom.js.map +1 -1
- package/dist/element.d.ts +2 -2
- package/dist/element.d.ts.map +1 -1
- package/dist/element.js +20 -32
- package/dist/element.js.map +1 -1
- package/dist/globalContext.d.ts +6 -1
- package/dist/globalContext.d.ts.map +1 -1
- package/dist/globalContext.js +14 -2
- package/dist/globalContext.js.map +1 -1
- package/dist/hooks/usePromise.d.ts +4 -9
- package/dist/hooks/usePromise.d.ts.map +1 -1
- package/dist/hooks/usePromise.js +25 -28
- package/dist/hooks/usePromise.js.map +1 -1
- package/dist/hooks/useRef.d.ts +2 -2
- package/dist/hooks/useRef.d.ts.map +1 -1
- package/dist/jsx.d.ts +1 -1
- package/dist/jsx.d.ts.map +1 -1
- package/dist/reconciler.d.ts +1 -1
- package/dist/reconciler.d.ts.map +1 -1
- package/dist/reconciler.js +57 -117
- package/dist/reconciler.js.map +1 -1
- package/dist/recursiveRender.d.ts +4 -3
- package/dist/recursiveRender.d.ts.map +1 -1
- package/dist/recursiveRender.js +20 -19
- package/dist/recursiveRender.js.map +1 -1
- package/dist/renderToString.js +2 -2
- package/dist/renderToString.js.map +1 -1
- package/dist/router/fileRouterController.d.ts +1 -1
- package/dist/router/fileRouterController.d.ts.map +1 -1
- package/dist/router/fileRouterController.js +11 -9
- package/dist/router/fileRouterController.js.map +1 -1
- package/dist/router/index.d.ts +1 -1
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/scrollStack.d.ts +0 -1
- package/dist/router/scrollStack.d.ts.map +1 -1
- package/dist/router/scrollStack.js +0 -3
- package/dist/router/scrollStack.js.map +1 -1
- package/dist/router/utils/index.d.ts +1 -1
- package/dist/router/utils/index.d.ts.map +1 -1
- package/dist/signals/base.d.ts +1 -3
- package/dist/signals/base.d.ts.map +1 -1
- package/dist/signals/base.js +3 -3
- package/dist/signals/base.js.map +1 -1
- package/dist/signals/computed.d.ts +4 -2
- package/dist/signals/computed.d.ts.map +1 -1
- package/dist/signals/computed.js +29 -6
- package/dist/signals/computed.js.map +1 -1
- package/dist/signals/for.d.ts +10 -0
- package/dist/signals/for.d.ts.map +1 -0
- package/dist/signals/for.js +7 -0
- package/dist/signals/for.js.map +1 -0
- package/dist/signals/index.d.ts +1 -1
- package/dist/signals/index.js +1 -1
- package/dist/signals/types.d.ts +1 -1
- package/dist/signals/types.d.ts.map +1 -1
- package/dist/ssr/server.js +13 -13
- package/dist/ssr/server.js.map +1 -1
- package/dist/types.d.ts +10 -11
- package/dist/types.d.ts.map +1 -1
- package/dist/types.dom.d.ts +33 -32
- package/dist/types.dom.d.ts.map +1 -1
- package/dist/types.utils.d.ts +5 -1
- package/dist/types.utils.d.ts.map +1 -1
- package/dist/utils/format.d.ts +2 -2
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js +4 -3
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +0 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/promise.d.ts +16 -0
- package/dist/utils/promise.d.ts.map +1 -0
- package/dist/utils/promise.js +14 -0
- package/dist/utils/promise.js.map +1 -0
- package/dist/utils/runtime.d.ts +10 -1
- package/dist/utils/runtime.d.ts.map +1 -1
- package/dist/utils/runtime.js +25 -1
- package/dist/utils/runtime.js.map +1 -1
- package/dist/utils/vdom.d.ts +4 -4
- package/dist/utils/vdom.d.ts.map +1 -1
- package/dist/utils/vdom.js +18 -17
- package/dist/utils/vdom.js.map +1 -1
- package/dist/vNode.d.ts +4 -0
- package/dist/vNode.d.ts.map +1 -0
- package/dist/vNode.js +22 -0
- package/dist/vNode.js.map +1 -0
- package/package.json +1 -1
- package/src/appContext.ts +15 -13
- package/src/components/derive.ts +121 -0
- package/src/components/index.ts +1 -1
- package/src/components/memo.ts +3 -2
- package/src/constants.ts +4 -4
- package/src/dom.ts +71 -66
- package/src/element.ts +22 -35
- package/src/globalContext.ts +24 -3
- package/src/hooks/usePromise.ts +32 -41
- package/src/hooks/useRef.ts +2 -2
- package/src/reconciler.ts +87 -125
- package/src/recursiveRender.ts +25 -23
- package/src/renderToString.ts +3 -3
- package/src/router/fileRouterController.ts +19 -9
- package/src/router/scrollStack.ts +23 -26
- package/src/signals/base.ts +3 -3
- package/src/signals/computed.ts +43 -6
- package/src/signals/for.ts +25 -0
- package/src/signals/index.ts +1 -1
- package/src/signals/types.ts +5 -1
- package/src/ssr/server.ts +15 -15
- package/src/types.dom.ts +40 -40
- package/src/types.ts +11 -11
- package/src/types.utils.ts +11 -1
- package/src/utils/format.ts +7 -4
- package/src/utils/index.ts +0 -2
- package/src/utils/promise.ts +26 -0
- package/src/utils/runtime.ts +29 -1
- package/src/utils/vdom.ts +20 -23
- package/src/vNode.ts +30 -0
- package/dist/components/suspense.d.ts +0 -24
- package/dist/components/suspense.d.ts.map +0 -1
- package/dist/components/suspense.js +0 -36
- package/dist/components/suspense.js.map +0 -1
- package/dist/signals/jsx.d.ts +0 -17
- package/dist/signals/jsx.d.ts.map +0 -1
- package/dist/signals/jsx.js +0 -11
- package/dist/signals/jsx.js.map +0 -1
- package/src/components/suspense.ts +0 -72
- package/src/signals/jsx.ts +0 -46
package/src/element.ts
CHANGED
|
@@ -1,46 +1,29 @@
|
|
|
1
|
-
import { $FRAGMENT
|
|
2
|
-
import {
|
|
3
|
-
import { isValidElementKeyProp, isValidElementRefProp } from "./utils/index.js"
|
|
1
|
+
import { $FRAGMENT } from "./constants.js"
|
|
2
|
+
import { normalizeElementKey } from "./utils/index.js"
|
|
4
3
|
|
|
5
4
|
export function createElement<T extends Kiru.VNode["type"]>(
|
|
6
5
|
type: T,
|
|
7
6
|
props: null | Record<string, unknown> = null,
|
|
8
7
|
...children: unknown[]
|
|
9
|
-
): Kiru.
|
|
10
|
-
if ((type as
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
const node: Kiru.VNode = {
|
|
14
|
-
type,
|
|
15
|
-
flags: 0,
|
|
16
|
-
index: 0,
|
|
17
|
-
depth: 0,
|
|
18
|
-
props: {},
|
|
19
|
-
parent: null,
|
|
20
|
-
sibling: null,
|
|
21
|
-
child: null,
|
|
22
|
-
prev: null,
|
|
23
|
-
deletions: null,
|
|
24
|
-
}
|
|
25
|
-
if (isMemoFn(type)) {
|
|
26
|
-
node.flags |= FLAG_MEMO
|
|
27
|
-
node.arePropsEqual = type[$MEMO].arePropsEqual
|
|
8
|
+
): Kiru.Element {
|
|
9
|
+
if ((type as unknown) === Fragment) {
|
|
10
|
+
type = $FRAGMENT as T
|
|
28
11
|
}
|
|
12
|
+
const p = props === null ? {} : props
|
|
13
|
+
const key = normalizeElementKey(p.key)
|
|
29
14
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
15
|
+
const len = children.length
|
|
16
|
+
if (len === 1) {
|
|
17
|
+
p.children = children[0]
|
|
18
|
+
} else if (len > 1) {
|
|
19
|
+
p.children = children
|
|
35
20
|
}
|
|
36
21
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
22
|
+
return {
|
|
23
|
+
type,
|
|
24
|
+
key,
|
|
25
|
+
props: p,
|
|
41
26
|
}
|
|
42
|
-
|
|
43
|
-
return node
|
|
44
27
|
}
|
|
45
28
|
|
|
46
29
|
export function Fragment({
|
|
@@ -49,6 +32,10 @@ export function Fragment({
|
|
|
49
32
|
}: {
|
|
50
33
|
children: JSX.Children
|
|
51
34
|
key?: JSX.ElementKey
|
|
52
|
-
}): Kiru.
|
|
53
|
-
return
|
|
35
|
+
}): Kiru.Element {
|
|
36
|
+
return {
|
|
37
|
+
type: $FRAGMENT,
|
|
38
|
+
key: normalizeElementKey(key),
|
|
39
|
+
props: { children },
|
|
40
|
+
}
|
|
54
41
|
}
|
package/src/globalContext.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type { FileRouterController } from "./router/fileRouterController"
|
|
|
6
6
|
import type { AppContext } from "./appContext"
|
|
7
7
|
import type { Store } from "./store"
|
|
8
8
|
import type { SWRCache } from "./swr"
|
|
9
|
+
import type { requestUpdate } from "./index.js"
|
|
9
10
|
|
|
10
11
|
export { createKiruGlobalContext, type GlobalKiruEvent, type KiruGlobalContext }
|
|
11
12
|
|
|
@@ -56,7 +57,7 @@ function createReactiveMap<V>(): ReactiveMap<V> {
|
|
|
56
57
|
type Evt =
|
|
57
58
|
| {
|
|
58
59
|
name: "mount"
|
|
59
|
-
data?:
|
|
60
|
+
data?: typeof requestUpdate
|
|
60
61
|
}
|
|
61
62
|
| {
|
|
62
63
|
name: "unmount"
|
|
@@ -73,6 +74,10 @@ type Evt =
|
|
|
73
74
|
|
|
74
75
|
type GlobalKiruEvent = Evt["name"]
|
|
75
76
|
|
|
77
|
+
interface SchedulerInterface {
|
|
78
|
+
requestUpdate: (vNode: Kiru.VNode) => void
|
|
79
|
+
}
|
|
80
|
+
|
|
76
81
|
interface KiruGlobalContext {
|
|
77
82
|
readonly apps: AppContext[]
|
|
78
83
|
emit<T extends Evt>(event: T["name"], ctx: AppContext, data?: T["data"]): void
|
|
@@ -91,10 +96,15 @@ interface KiruGlobalContext {
|
|
|
91
96
|
fileRouterInstance?: {
|
|
92
97
|
current: FileRouterController | null
|
|
93
98
|
}
|
|
99
|
+
getSchedulerInterface?: (app: AppContext) => SchedulerInterface | null
|
|
94
100
|
}
|
|
95
101
|
|
|
96
102
|
function createKiruGlobalContext(): KiruGlobalContext {
|
|
97
103
|
const contexts = new Set<AppContext>()
|
|
104
|
+
const contextToSchedulerInterface = new WeakMap<
|
|
105
|
+
AppContext,
|
|
106
|
+
SchedulerInterface
|
|
107
|
+
>()
|
|
98
108
|
const listeners = new Map<
|
|
99
109
|
GlobalKiruEvent,
|
|
100
110
|
Set<(ctx: AppContext, data?: Evt["data"]) => void>
|
|
@@ -134,14 +144,25 @@ function createKiruGlobalContext(): KiruGlobalContext {
|
|
|
134
144
|
}
|
|
135
145
|
|
|
136
146
|
// Initialize event listeners
|
|
137
|
-
on("mount", (ctx) =>
|
|
138
|
-
|
|
147
|
+
on("mount", (ctx, requestUpdate) => {
|
|
148
|
+
contexts.add(ctx)
|
|
149
|
+
if (requestUpdate && typeof requestUpdate === "function") {
|
|
150
|
+
contextToSchedulerInterface.set(ctx, { requestUpdate })
|
|
151
|
+
}
|
|
152
|
+
})
|
|
153
|
+
on("unmount", (ctx) => {
|
|
154
|
+
contexts.delete(ctx)
|
|
155
|
+
contextToSchedulerInterface.delete(ctx)
|
|
156
|
+
})
|
|
139
157
|
|
|
140
158
|
if (__DEV__) {
|
|
141
159
|
globalContext.HMRContext = createHMRContext()
|
|
142
160
|
globalContext.profilingContext = createProfilingContext()
|
|
143
161
|
globalContext.stores = createReactiveMap()
|
|
144
162
|
globalContext.fileRouterInstance = fileRouterInstance
|
|
163
|
+
globalContext.getSchedulerInterface = (app) => {
|
|
164
|
+
return contextToSchedulerInterface.get(app) ?? null
|
|
165
|
+
}
|
|
145
166
|
}
|
|
146
167
|
|
|
147
168
|
return globalContext
|
package/src/hooks/usePromise.ts
CHANGED
|
@@ -1,43 +1,36 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { STREAMED_DATA_EVENT } from "../constants.js"
|
|
2
2
|
import { __DEV__ } from "../env.js"
|
|
3
3
|
import { hydrationMode, renderMode } from "../globals.js"
|
|
4
|
-
import { requestUpdate } from "../scheduler.js"
|
|
5
4
|
import { Signal, useSignal } from "../signals/base.js"
|
|
6
5
|
import { cleanupHook, depsRequireChange, useHook } from "./utils.js"
|
|
7
6
|
import { useId } from "./useId.js"
|
|
8
7
|
|
|
9
8
|
export { usePromise }
|
|
10
|
-
export type { UsePromiseCallbackContext, UsePromiseState }
|
|
11
9
|
|
|
12
10
|
const nodeToPromiseIndex = new WeakMap<Kiru.VNode, number>()
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
signal: AbortSignal
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
interface UsePromiseState<T> {
|
|
19
|
-
data: Kiru.StatefulPromise<T>
|
|
12
|
+
type UsePromiseResult<T> = Kiru.StatefulPromise<T> & {
|
|
20
13
|
refresh: () => void
|
|
21
|
-
|
|
14
|
+
isPending: Signal<boolean>
|
|
22
15
|
}
|
|
23
16
|
|
|
24
17
|
function usePromise<T>(
|
|
25
|
-
callback: (
|
|
18
|
+
callback: (signal: AbortSignal) => Promise<T>,
|
|
26
19
|
deps: unknown[]
|
|
27
|
-
):
|
|
20
|
+
): UsePromiseResult<T> {
|
|
28
21
|
const id = useId()
|
|
29
|
-
const
|
|
22
|
+
const isPending = useSignal(true)
|
|
30
23
|
|
|
31
24
|
return useHook(
|
|
32
25
|
"usePromise",
|
|
33
26
|
{} as {
|
|
34
|
-
promise:
|
|
27
|
+
promise: UsePromiseResult<T>
|
|
35
28
|
abortController?: AbortController
|
|
36
29
|
deps?: unknown[]
|
|
37
30
|
},
|
|
38
|
-
({ hook, isInit, vNode }) => {
|
|
31
|
+
({ hook, isInit, vNode, update }) => {
|
|
39
32
|
if (isInit || depsRequireChange(deps, hook.deps)) {
|
|
40
|
-
|
|
33
|
+
isPending.value = true
|
|
41
34
|
hook.deps = deps
|
|
42
35
|
cleanupHook(hook)
|
|
43
36
|
|
|
@@ -59,77 +52,75 @@ function usePromise<T>(
|
|
|
59
52
|
) {
|
|
60
53
|
// if we're hydrating and the hydration mode is not static,
|
|
61
54
|
// we need to resolve the promise from cache/event
|
|
62
|
-
promise =
|
|
55
|
+
promise = resolveDeferredPromise<T>(promiseId, controller.signal)
|
|
63
56
|
} else {
|
|
64
57
|
// dom / stream / (hydrate + static)
|
|
65
|
-
promise = callback(
|
|
58
|
+
promise = callback(controller.signal)
|
|
66
59
|
}
|
|
67
60
|
|
|
68
61
|
const state: Kiru.PromiseState<T> = { id: promiseId, state: "pending" }
|
|
69
|
-
const statefulPromise = (hook.promise =
|
|
62
|
+
const statefulPromise: Kiru.StatefulPromise<T> = (hook.promise =
|
|
63
|
+
Object.assign(promise, state, {
|
|
64
|
+
isPending,
|
|
65
|
+
refresh: () => {
|
|
66
|
+
hook.deps = undefined
|
|
67
|
+
update()
|
|
68
|
+
},
|
|
69
|
+
}))
|
|
70
70
|
|
|
71
71
|
statefulPromise
|
|
72
72
|
.then((value) => {
|
|
73
73
|
statefulPromise.state = "fulfilled"
|
|
74
74
|
statefulPromise.value = value
|
|
75
|
+
isPending.value = false
|
|
75
76
|
})
|
|
76
77
|
.catch((error) => {
|
|
77
78
|
statefulPromise.state = "rejected"
|
|
78
79
|
statefulPromise.error =
|
|
79
80
|
error instanceof Error ? error : new Error(error)
|
|
80
81
|
})
|
|
81
|
-
.finally(() => {
|
|
82
|
-
pending.value = false
|
|
83
|
-
})
|
|
84
|
-
}
|
|
85
|
-
return {
|
|
86
|
-
data: hook.promise,
|
|
87
|
-
refresh: () => {
|
|
88
|
-
hook.deps = undefined
|
|
89
|
-
requestUpdate(vNode)
|
|
90
|
-
},
|
|
91
|
-
pending,
|
|
92
82
|
}
|
|
83
|
+
return hook.promise
|
|
93
84
|
}
|
|
94
85
|
)
|
|
95
86
|
}
|
|
96
87
|
|
|
97
|
-
interface
|
|
88
|
+
interface DeferredPromiseEventDetail<T> {
|
|
98
89
|
id: string
|
|
99
90
|
data?: T
|
|
100
91
|
error?: string
|
|
101
92
|
}
|
|
102
93
|
|
|
103
|
-
function
|
|
94
|
+
function resolveDeferredPromise<T>(
|
|
104
95
|
id: string,
|
|
105
96
|
signal: AbortSignal
|
|
106
97
|
): Promise<T> {
|
|
107
98
|
return new Promise<T>((resolve, reject) => {
|
|
108
|
-
const
|
|
109
|
-
(window[
|
|
99
|
+
const deferralCache: Map<string, { data?: T; error?: string }> = // @ts-ignore
|
|
100
|
+
(window[STREAMED_DATA_EVENT] ??= new Map())
|
|
110
101
|
|
|
111
|
-
const existing =
|
|
102
|
+
const existing = deferralCache.get(id)
|
|
112
103
|
if (existing) {
|
|
113
104
|
const { data, error } = existing
|
|
114
|
-
|
|
105
|
+
deferralCache.delete(id)
|
|
115
106
|
if (error) return reject(error)
|
|
116
107
|
return resolve(data!)
|
|
117
108
|
}
|
|
118
109
|
|
|
119
110
|
const onDataEvent = (event: Event) => {
|
|
120
|
-
const { detail } = event as CustomEvent<
|
|
111
|
+
const { detail } = event as CustomEvent<DeferredPromiseEventDetail<T>>
|
|
121
112
|
if (detail.id === id) {
|
|
122
|
-
|
|
123
|
-
window.removeEventListener(
|
|
113
|
+
deferralCache.delete(id)
|
|
114
|
+
window.removeEventListener(STREAMED_DATA_EVENT, onDataEvent)
|
|
124
115
|
const { data, error } = detail
|
|
125
116
|
if (error) return reject(error)
|
|
126
117
|
resolve(data!)
|
|
127
118
|
}
|
|
128
119
|
}
|
|
129
120
|
|
|
130
|
-
window.addEventListener(
|
|
121
|
+
window.addEventListener(STREAMED_DATA_EVENT, onDataEvent)
|
|
131
122
|
signal.addEventListener("abort", () => {
|
|
132
|
-
window.removeEventListener(
|
|
123
|
+
window.removeEventListener(STREAMED_DATA_EVENT, onDataEvent)
|
|
133
124
|
reject()
|
|
134
125
|
})
|
|
135
126
|
})
|
package/src/hooks/useRef.ts
CHANGED
|
@@ -8,9 +8,9 @@ import { useHook } from "./utils.js"
|
|
|
8
8
|
*
|
|
9
9
|
* @see https://kirujs.dev/docs/hooks/useRef
|
|
10
10
|
*/
|
|
11
|
-
export function useRef<T>(initialValue: T): Kiru.
|
|
11
|
+
export function useRef<T>(initialValue: T): Kiru.RefObject<T>
|
|
12
12
|
export function useRef<T>(initialValue: T | null): Kiru.RefObject<T>
|
|
13
|
-
export function useRef<T = undefined>(): Kiru.
|
|
13
|
+
export function useRef<T = undefined>(): Kiru.RefObject<T | undefined>
|
|
14
14
|
export function useRef<T>(initialValue?: T | null) {
|
|
15
15
|
if (!sideEffectsEnabled()) return { current: initialValue }
|
|
16
16
|
return useHook(
|