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/signals/computed.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __DEV__ } from "../env.js"
|
|
2
2
|
import { $HMR_ACCEPT } from "../constants.js"
|
|
3
|
-
import { useHook } from "../hooks/utils.js"
|
|
3
|
+
import { depsRequireChange, useHook } from "../hooks/utils.js"
|
|
4
4
|
import { latest } from "../utils/index.js"
|
|
5
5
|
import { effectQueue, signalSubsMap } from "./globals.js"
|
|
6
6
|
import { executeWithTracking } from "./effect.js"
|
|
@@ -69,6 +69,16 @@ export class ComputedSignal<T> extends Signal<T> {
|
|
|
69
69
|
Signal.dispose(signal)
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
static updateGetter<T>(signal: ComputedSignal<T>, getter: (prev?: T) => T) {
|
|
73
|
+
const $computed = latest(signal)
|
|
74
|
+
$computed.$getter = getter
|
|
75
|
+
$computed.$isDirty = true
|
|
76
|
+
|
|
77
|
+
ComputedSignal.run($computed)
|
|
78
|
+
if (Object.is($computed.$value, $computed.$prevValue)) return
|
|
79
|
+
$computed.notify()
|
|
80
|
+
}
|
|
81
|
+
|
|
72
82
|
private static stop<T>(computed: ComputedSignal<T>) {
|
|
73
83
|
const { $id, $unsubs } = latest(computed)
|
|
74
84
|
|
|
@@ -103,20 +113,35 @@ export class ComputedSignal<T> extends Signal<T> {
|
|
|
103
113
|
}
|
|
104
114
|
}
|
|
105
115
|
|
|
106
|
-
export
|
|
116
|
+
export function computed<T>(
|
|
107
117
|
getter: (prev?: T) => T,
|
|
108
118
|
displayName?: string
|
|
109
|
-
): ComputedSignal<T>
|
|
119
|
+
): ComputedSignal<T> {
|
|
110
120
|
return new ComputedSignal(getter, displayName)
|
|
111
121
|
}
|
|
112
122
|
|
|
113
|
-
export
|
|
123
|
+
export function useComputed<T>(
|
|
124
|
+
getter: (prev?: T) => T,
|
|
125
|
+
displayName?: string
|
|
126
|
+
): ComputedSignal<T>
|
|
127
|
+
|
|
128
|
+
export function useComputed<T>(
|
|
114
129
|
getter: (prev?: T) => T,
|
|
130
|
+
deps?: unknown[],
|
|
115
131
|
displayName?: string
|
|
116
|
-
)
|
|
132
|
+
): ComputedSignal<T>
|
|
133
|
+
|
|
134
|
+
export function useComputed<T>(
|
|
135
|
+
getter: (prev?: T) => T,
|
|
136
|
+
depsOrDisplayName?: string | unknown[],
|
|
137
|
+
displayName?: string
|
|
138
|
+
) {
|
|
117
139
|
return useHook(
|
|
118
140
|
"useComputedSignal",
|
|
119
|
-
{
|
|
141
|
+
{
|
|
142
|
+
signal: null! as ComputedSignal<T>,
|
|
143
|
+
deps: void 0 as unknown[] | undefined,
|
|
144
|
+
},
|
|
120
145
|
({ hook, isInit, isHMR }) => {
|
|
121
146
|
if (__DEV__) {
|
|
122
147
|
hook.dev = {
|
|
@@ -134,8 +159,20 @@ export const useComputed = <T>(
|
|
|
134
159
|
}
|
|
135
160
|
}
|
|
136
161
|
if (isInit) {
|
|
162
|
+
if (typeof depsOrDisplayName === "string") {
|
|
163
|
+
displayName = depsOrDisplayName
|
|
164
|
+
depsOrDisplayName = void 0
|
|
165
|
+
}
|
|
166
|
+
hook.deps = depsOrDisplayName
|
|
137
167
|
hook.cleanup = () => ComputedSignal.dispose(hook.signal)
|
|
138
168
|
hook.signal = computed(getter, displayName)
|
|
169
|
+
} else if (
|
|
170
|
+
hook.deps &&
|
|
171
|
+
typeof depsOrDisplayName !== "string" &&
|
|
172
|
+
depsRequireChange(hook.deps, depsOrDisplayName)
|
|
173
|
+
) {
|
|
174
|
+
hook.deps = depsOrDisplayName
|
|
175
|
+
ComputedSignal.updateGetter(hook.signal, getter)
|
|
139
176
|
}
|
|
140
177
|
|
|
141
178
|
return hook.signal
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Signal } from "./base.js"
|
|
2
|
+
|
|
3
|
+
type InferArraySignalItemType<T extends Signal<any[]>> = T extends Signal<
|
|
4
|
+
infer V
|
|
5
|
+
>
|
|
6
|
+
? V extends Array<infer W>
|
|
7
|
+
? W
|
|
8
|
+
: never
|
|
9
|
+
: never
|
|
10
|
+
|
|
11
|
+
type ForProps<T extends Signal<any[]>, U = InferArraySignalItemType<T>> = {
|
|
12
|
+
each: T
|
|
13
|
+
fallback?: JSX.Element
|
|
14
|
+
children: (value: U, index: number, array: U[]) => JSX.Element
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function For<T extends Signal<any[]>>({
|
|
18
|
+
each,
|
|
19
|
+
fallback,
|
|
20
|
+
children,
|
|
21
|
+
}: ForProps<T>) {
|
|
22
|
+
const items = each.value
|
|
23
|
+
if (items.length === 0) return fallback
|
|
24
|
+
return items.map(children)
|
|
25
|
+
}
|
package/src/signals/index.ts
CHANGED
|
@@ -8,5 +8,5 @@ export { Signal, signal, useSignal } from "./base.js"
|
|
|
8
8
|
export { ComputedSignal, computed, useComputed } from "./computed.js"
|
|
9
9
|
export { WatchEffect, watch, useWatch } from "./watch.js"
|
|
10
10
|
export { unwrap, tick } from "./utils.js"
|
|
11
|
-
export * from "./
|
|
11
|
+
export * from "./for.js"
|
|
12
12
|
export * from "./types.js"
|
package/src/signals/types.ts
CHANGED
|
@@ -6,5 +6,9 @@ export type ReadonlySignal<T> = Signal<T> & {
|
|
|
6
6
|
export type SignalSubscriber<T = unknown> = (value: T, prevValue?: T) => void
|
|
7
7
|
|
|
8
8
|
export type SignalValues<T extends readonly Signal<unknown>[]> = {
|
|
9
|
-
[I in keyof T]: T[I] extends Signal<infer V>
|
|
9
|
+
[I in keyof T]: T[I] extends Signal<infer V>
|
|
10
|
+
? V extends Kiru.StatefulPromise<infer P>
|
|
11
|
+
? P
|
|
12
|
+
: V
|
|
13
|
+
: never
|
|
10
14
|
}
|
package/src/ssr/server.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { Readable } from "node:stream"
|
|
2
2
|
import { Fragment } from "../element.js"
|
|
3
3
|
import { renderMode } from "../globals.js"
|
|
4
|
-
import {
|
|
4
|
+
import { STREAMED_DATA_EVENT } from "../constants.js"
|
|
5
5
|
import { __DEV__ } from "../env.js"
|
|
6
|
-
import {
|
|
6
|
+
import { headlessRender, HeadlessRenderContext } from "../recursiveRender.js"
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const STREAMED_DATA_SETUP = `
|
|
9
9
|
<script type="text/javascript">
|
|
10
10
|
const d = document,
|
|
11
|
-
m = (window["${
|
|
12
|
-
d.querySelectorAll("[
|
|
11
|
+
m = (window["${STREAMED_DATA_EVENT}"] ??= new Map());
|
|
12
|
+
d.querySelectorAll("[k-data]").forEach((p) => {
|
|
13
13
|
const id = p.getAttribute("id");
|
|
14
14
|
const { data, error } = JSON.parse(p.innerHTML);
|
|
15
15
|
m.set(id, { data, error });
|
|
16
|
-
const event = new CustomEvent("${
|
|
16
|
+
const event = new CustomEvent("${STREAMED_DATA_EVENT}", { detail: { id, data, error } });
|
|
17
17
|
window.dispatchEvent(event);
|
|
18
18
|
p.remove();
|
|
19
19
|
});
|
|
@@ -27,17 +27,17 @@ export function renderToReadableStream(element: JSX.Element): {
|
|
|
27
27
|
} {
|
|
28
28
|
const stream = new Readable({ read() {} })
|
|
29
29
|
const rootNode = Fragment({ children: element })
|
|
30
|
-
const
|
|
31
|
-
const pendingWritePromises: Promise<
|
|
30
|
+
const streamPromises = new Set<Kiru.StatefulPromise<unknown>>()
|
|
31
|
+
const pendingWritePromises: Promise<void>[] = []
|
|
32
32
|
|
|
33
33
|
let immediate = ""
|
|
34
34
|
|
|
35
|
-
const ctx:
|
|
35
|
+
const ctx: HeadlessRenderContext = {
|
|
36
36
|
write: (chunk) => (immediate += chunk),
|
|
37
|
-
|
|
37
|
+
onStreamData(data) {
|
|
38
38
|
for (const promise of data) {
|
|
39
|
-
if (
|
|
40
|
-
|
|
39
|
+
if (streamPromises.has(promise)) continue
|
|
40
|
+
streamPromises.add(promise)
|
|
41
41
|
|
|
42
42
|
const writePromise = promise
|
|
43
43
|
.then(() => ({ data: promise.value }))
|
|
@@ -45,7 +45,7 @@ export function renderToReadableStream(element: JSX.Element): {
|
|
|
45
45
|
.then((value) => {
|
|
46
46
|
const content = JSON.stringify(value)
|
|
47
47
|
stream.push(
|
|
48
|
-
`<script id="${promise.id}"
|
|
48
|
+
`<script id="${promise.id}" k-data type="application/json">${content}</script>`
|
|
49
49
|
)
|
|
50
50
|
})
|
|
51
51
|
|
|
@@ -56,12 +56,12 @@ export function renderToReadableStream(element: JSX.Element): {
|
|
|
56
56
|
|
|
57
57
|
const prev = renderMode.current
|
|
58
58
|
renderMode.current = "stream"
|
|
59
|
-
|
|
59
|
+
headlessRender(ctx, rootNode, null, 0)
|
|
60
60
|
renderMode.current = prev
|
|
61
61
|
|
|
62
62
|
if (pendingWritePromises.length > 0) {
|
|
63
63
|
Promise.all(pendingWritePromises).then(() => {
|
|
64
|
-
stream.push(
|
|
64
|
+
stream.push(STREAMED_DATA_SETUP)
|
|
65
65
|
stream.push(null)
|
|
66
66
|
})
|
|
67
67
|
} else {
|
package/src/types.dom.ts
CHANGED
|
@@ -352,6 +352,8 @@ type NoChildElementElement =
|
|
|
352
352
|
| HTMLTrackElement
|
|
353
353
|
| HTMLTextAreaElement
|
|
354
354
|
|
|
355
|
+
type DomElement = Element
|
|
356
|
+
|
|
355
357
|
declare global {
|
|
356
358
|
namespace Kiru {
|
|
357
359
|
type DOMEvent<E = Event, C = unknown, T = unknown> = Omit<
|
|
@@ -368,98 +370,96 @@ declare global {
|
|
|
368
370
|
bivarianceHack(event: E): void
|
|
369
371
|
}["bivarianceHack"]
|
|
370
372
|
|
|
371
|
-
interface BaseEvent<T extends
|
|
373
|
+
interface BaseEvent<T extends DomElement = DomElement>
|
|
372
374
|
extends DOMEvent<Event, T> {}
|
|
373
375
|
|
|
374
|
-
interface AnimationEvent<T extends
|
|
376
|
+
interface AnimationEvent<T extends DomElement = DomElement>
|
|
375
377
|
extends DOMEvent<NativeAnimationEvent, T> {}
|
|
376
378
|
|
|
377
|
-
interface ClipboardEvent<T extends
|
|
379
|
+
interface ClipboardEvent<T extends DomElement = DomElement>
|
|
378
380
|
extends DOMEvent<NativeClipboardEvent, T> {}
|
|
379
381
|
|
|
380
|
-
interface CompositionEvent<T extends
|
|
382
|
+
interface CompositionEvent<T extends DomElement = DomElement>
|
|
381
383
|
extends DOMEvent<NativeCompositionEvent, T> {}
|
|
382
384
|
|
|
383
|
-
interface DragEvent<T extends
|
|
385
|
+
interface DragEvent<T extends DomElement = DomElement>
|
|
384
386
|
extends DOMEvent<NativeDragEvent, T> {}
|
|
385
387
|
|
|
386
|
-
interface FocusEvent<T extends
|
|
388
|
+
interface FocusEvent<T extends DomElement = DomElement>
|
|
387
389
|
extends DOMEvent<NativeFocusEvent, T> {}
|
|
388
390
|
|
|
389
|
-
interface FormEvent<T extends
|
|
391
|
+
interface FormEvent<T extends DomElement = DomElement>
|
|
390
392
|
extends DOMEvent<Event, T> {}
|
|
391
393
|
|
|
392
|
-
interface KeyboardEvent<T extends
|
|
394
|
+
interface KeyboardEvent<T extends DomElement = DomElement>
|
|
393
395
|
extends DOMEvent<NativeKeyboardEvent, T> {}
|
|
394
396
|
|
|
395
|
-
interface MouseEvent<T extends
|
|
397
|
+
interface MouseEvent<T extends DomElement = DomElement>
|
|
396
398
|
extends DOMEvent<NativeMouseEvent, T> {}
|
|
397
399
|
|
|
398
|
-
interface PointerEvent<T extends
|
|
400
|
+
interface PointerEvent<T extends DomElement = DomElement>
|
|
399
401
|
extends DOMEvent<NativePointerEvent, T> {}
|
|
400
402
|
|
|
401
|
-
interface SubmitEvent<T extends
|
|
403
|
+
interface SubmitEvent<T extends DomElement = DomElement>
|
|
402
404
|
extends DOMEvent<NativeSubmitEvent, T> {}
|
|
403
405
|
|
|
404
|
-
interface TouchEvent<T extends
|
|
406
|
+
interface TouchEvent<T extends DomElement = DomElement>
|
|
405
407
|
extends DOMEvent<NativeTouchEvent, T> {}
|
|
406
408
|
|
|
407
|
-
interface ToggleEvent<T extends
|
|
409
|
+
interface ToggleEvent<T extends DomElement = DomElement>
|
|
408
410
|
extends DOMEvent<NativeToggleEvent, T> {}
|
|
409
411
|
|
|
410
|
-
interface TransitionEvent<T extends
|
|
412
|
+
interface TransitionEvent<T extends DomElement = DomElement>
|
|
411
413
|
extends DOMEvent<NativeTransitionEvent, T> {}
|
|
412
414
|
|
|
413
|
-
interface UIEvent<T extends
|
|
415
|
+
interface UIEvent<T extends DomElement = DomElement>
|
|
414
416
|
extends DOMEvent<NativeUIEvent, T> {}
|
|
415
417
|
|
|
416
|
-
interface WheelEvent<T extends
|
|
418
|
+
interface WheelEvent<T extends DomElement = DomElement>
|
|
417
419
|
extends DOMEvent<NativeWheelEvent, T> {}
|
|
418
420
|
|
|
419
|
-
type BaseEventHandler<T extends
|
|
421
|
+
type BaseEventHandler<T extends DomElement = DomElement> = EventHandler<
|
|
420
422
|
BaseEvent<T>
|
|
421
423
|
>
|
|
422
424
|
|
|
423
|
-
type ClipboardEventHandler<T extends
|
|
424
|
-
ClipboardEvent<T
|
|
425
|
-
>
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
>
|
|
429
|
-
type DragEventHandler<T extends Element = Element> = EventHandler<
|
|
425
|
+
type ClipboardEventHandler<T extends DomElement = DomElement> =
|
|
426
|
+
EventHandler<ClipboardEvent<T>>
|
|
427
|
+
type CompositionEventHandler<T extends DomElement = DomElement> =
|
|
428
|
+
EventHandler<CompositionEvent<T>>
|
|
429
|
+
type DragEventHandler<T extends DomElement = DomElement> = EventHandler<
|
|
430
430
|
DragEvent<T>
|
|
431
431
|
>
|
|
432
|
-
type FocusEventHandler<T extends
|
|
432
|
+
type FocusEventHandler<T extends DomElement = DomElement> = EventHandler<
|
|
433
433
|
FocusEvent<T>
|
|
434
434
|
>
|
|
435
|
-
type FormEventHandler<T extends
|
|
435
|
+
type FormEventHandler<T extends DomElement = DomElement> = EventHandler<
|
|
436
436
|
FormEvent<T>
|
|
437
437
|
>
|
|
438
|
-
type KeyboardEventHandler<T extends
|
|
438
|
+
type KeyboardEventHandler<T extends DomElement = DomElement> = EventHandler<
|
|
439
439
|
KeyboardEvent<T>
|
|
440
440
|
>
|
|
441
|
-
type MouseEventHandler<T extends
|
|
441
|
+
type MouseEventHandler<T extends DomElement = DomElement> = EventHandler<
|
|
442
442
|
MouseEvent<T>
|
|
443
443
|
>
|
|
444
|
-
type TouchEventHandler<T extends
|
|
444
|
+
type TouchEventHandler<T extends DomElement = DomElement> = EventHandler<
|
|
445
445
|
TouchEvent<T>
|
|
446
446
|
>
|
|
447
|
-
type PointerEventHandler<T extends
|
|
447
|
+
type PointerEventHandler<T extends DomElement = DomElement> = EventHandler<
|
|
448
448
|
PointerEvent<T>
|
|
449
449
|
>
|
|
450
|
-
type UIEventHandler<T extends
|
|
451
|
-
|
|
452
|
-
WheelEvent<T>
|
|
450
|
+
type UIEventHandler<T extends DomElement = DomElement> = EventHandler<
|
|
451
|
+
UIEvent<T>
|
|
453
452
|
>
|
|
454
|
-
type
|
|
455
|
-
|
|
453
|
+
type WheelEventHandler<T extends DomElement = DomElement> = EventHandler<
|
|
454
|
+
WheelEvent<T>
|
|
456
455
|
>
|
|
457
|
-
type
|
|
456
|
+
type AnimationEventHandler<T extends DomElement = DomElement> =
|
|
457
|
+
EventHandler<AnimationEvent<T>>
|
|
458
|
+
type ToggleEventHandler<T extends DomElement = DomElement> = EventHandler<
|
|
458
459
|
ToggleEvent<T>
|
|
459
460
|
>
|
|
460
|
-
type TransitionEventHandler<T extends
|
|
461
|
-
TransitionEvent<T
|
|
462
|
-
>
|
|
461
|
+
type TransitionEventHandler<T extends DomElement = DomElement> =
|
|
462
|
+
EventHandler<TransitionEvent<T>>
|
|
463
463
|
|
|
464
464
|
type CustomEventAttributes = {
|
|
465
465
|
[Key in keyof Kiru.CustomEvents as `on:${Key}`]?: (
|
|
@@ -467,7 +467,7 @@ declare global {
|
|
|
467
467
|
) => void
|
|
468
468
|
}
|
|
469
469
|
|
|
470
|
-
interface EventAttributes<T extends
|
|
470
|
+
interface EventAttributes<T extends DomElement = DomElement>
|
|
471
471
|
extends CustomEventAttributes {
|
|
472
472
|
// Clipboard Events
|
|
473
473
|
oncopy?: ClipboardEventHandler<T> | undefined
|
package/src/types.ts
CHANGED
|
@@ -103,7 +103,7 @@ declare global {
|
|
|
103
103
|
|
|
104
104
|
type Element =
|
|
105
105
|
| Element[]
|
|
106
|
-
| Kiru.
|
|
106
|
+
| Kiru.Element
|
|
107
107
|
| PrimitiveChild
|
|
108
108
|
| Kiru.Signal<PrimitiveChild>
|
|
109
109
|
|
|
@@ -156,16 +156,13 @@ declare global {
|
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
interface RefObject<T> {
|
|
159
|
-
readonly current: T | null
|
|
160
|
-
}
|
|
161
|
-
interface MutableRefObject<T> {
|
|
162
159
|
current: T
|
|
163
160
|
}
|
|
164
161
|
type RefCallback<T> = {
|
|
165
162
|
bivarianceHack(instance: T | null): void
|
|
166
163
|
}["bivarianceHack"]
|
|
167
164
|
|
|
168
|
-
type Ref<T> = RefCallback<T> | RefObject<T>
|
|
165
|
+
type Ref<T> = RefCallback<T> | RefObject<T>
|
|
169
166
|
|
|
170
167
|
interface PromiseState<T> {
|
|
171
168
|
id: string
|
|
@@ -187,25 +184,27 @@ declare global {
|
|
|
187
184
|
| typeof $CONTEXT_PROVIDER
|
|
188
185
|
| typeof $ERROR_BOUNDARY
|
|
189
186
|
|
|
190
|
-
interface
|
|
191
|
-
app?: AppContext
|
|
192
|
-
dom?: SomeDom
|
|
193
|
-
lastChildDom?: SomeDom
|
|
187
|
+
interface Element {
|
|
194
188
|
type: Function | ExoticSymbol | "#text" | (string & {})
|
|
189
|
+
key: JSX.ElementKey | null
|
|
195
190
|
props: {
|
|
196
191
|
[key: string]: any
|
|
197
192
|
children?: unknown
|
|
198
|
-
key?: JSX.ElementKey
|
|
199
193
|
ref?: Kiru.Ref<unknown>
|
|
200
194
|
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
interface VNode extends Element {
|
|
198
|
+
app?: AppContext
|
|
199
|
+
dom?: SomeDom
|
|
201
200
|
index: number
|
|
202
201
|
depth: number
|
|
202
|
+
flags: number
|
|
203
203
|
parent: VNode | null
|
|
204
204
|
child: VNode | null
|
|
205
205
|
sibling: VNode | null
|
|
206
206
|
prev: VNodeSnapshot | null
|
|
207
207
|
deletions: VNode[] | null
|
|
208
|
-
flags: number
|
|
209
208
|
hooks?: Hook<unknown>[]
|
|
210
209
|
subs?: Set<Function>
|
|
211
210
|
cleanups?: Record<string, Function>
|
|
@@ -223,6 +222,7 @@ declare global {
|
|
|
223
222
|
}
|
|
224
223
|
interface VNodeSnapshot {
|
|
225
224
|
props: Kiru.VNode["props"]
|
|
225
|
+
key: Kiru.VNode["key"]
|
|
226
226
|
memoizedProps: Kiru.VNode["memoizedProps"]
|
|
227
227
|
index: number
|
|
228
228
|
}
|
package/src/types.utils.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type MaybeElement = SomeElement | undefined
|
|
|
8
8
|
export type MaybeDom = SomeDom | undefined
|
|
9
9
|
|
|
10
10
|
export interface FunctionVNode extends Kiru.VNode {
|
|
11
|
-
type: (
|
|
11
|
+
type: (props: Record<string, unknown>) => JSX.Element
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export interface ElementVNode extends Kiru.VNode {
|
|
@@ -65,3 +65,13 @@ export type AsyncTaskState<T, E extends Error = Error> =
|
|
|
65
65
|
export type Guard<T, K extends keyof T> = {
|
|
66
66
|
[P in K]: T[P]
|
|
67
67
|
}
|
|
68
|
+
|
|
69
|
+
export type ArrayHas<T extends any[], U> =
|
|
70
|
+
// does the union of element types intersect U?
|
|
71
|
+
Extract<T[number], U> extends never ? false : true
|
|
72
|
+
|
|
73
|
+
export type RecordHas<T extends Record<string, any>, U> = [
|
|
74
|
+
Extract<T[keyof T], U>
|
|
75
|
+
] extends [never]
|
|
76
|
+
? false
|
|
77
|
+
: true
|
package/src/utils/format.ts
CHANGED
|
@@ -34,11 +34,14 @@ function encodeHtmlEntities(text: string): string {
|
|
|
34
34
|
.replace(REGEX_SLASH, "/")
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
const internalProps = new Set(["children", "ref", "key", "innerHTML"])
|
|
37
38
|
const propFilters = {
|
|
38
|
-
|
|
39
|
+
isInternalProp: (
|
|
40
|
+
key: string
|
|
41
|
+
): key is "children" | "ref" | "key" | "innerHTML" => internalProps.has(key),
|
|
39
42
|
isEvent: (key: string) => key.startsWith("on"),
|
|
40
|
-
|
|
41
|
-
!
|
|
43
|
+
isStringRenderableProperty: (key: string) =>
|
|
44
|
+
!internalProps.has(key) && !propFilters.isEvent(key),
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
function propToHtmlAttr(key: string): string {
|
|
@@ -110,7 +113,7 @@ function propsToElementAttributes(props: Record<string, unknown>): string {
|
|
|
110
113
|
if (!!val) attrs.push(`style="${stylePropToString(val)}"`)
|
|
111
114
|
}
|
|
112
115
|
|
|
113
|
-
const keys = Object.keys(rest).filter(propFilters.
|
|
116
|
+
const keys = Object.keys(rest).filter(propFilters.isStringRenderableProperty)
|
|
114
117
|
for (let i = 0; i < keys.length; i++) {
|
|
115
118
|
let k = keys[i]
|
|
116
119
|
let val = unwrap(props[k])
|
package/src/utils/index.ts
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { $STREAM_DATA } from "../constants.js"
|
|
2
|
+
|
|
3
|
+
export interface StreamDataThrowValue {
|
|
4
|
+
[$STREAM_DATA]: {
|
|
5
|
+
fallback?: JSX.Element
|
|
6
|
+
data: Kiru.StatefulPromise<unknown>[]
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Returns true if the value is a {@link StreamDataThrowValue}
|
|
12
|
+
*/
|
|
13
|
+
export function isStreamDataThrowValue(
|
|
14
|
+
value: unknown
|
|
15
|
+
): value is StreamDataThrowValue {
|
|
16
|
+
return typeof value === "object" && !!value && $STREAM_DATA in value
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Returns true if the value is a {@link Kiru.StatefulPromise}
|
|
21
|
+
*/
|
|
22
|
+
export function isStatefulPromise(
|
|
23
|
+
thing: unknown
|
|
24
|
+
): thing is Kiru.StatefulPromise<unknown> {
|
|
25
|
+
return thing instanceof Promise && "id" in thing && "state" in thing
|
|
26
|
+
}
|
package/src/utils/runtime.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { Signal } from "../signals/base.js"
|
|
1
2
|
import { __DEV__ } from "../env.js"
|
|
2
3
|
import { renderMode } from "../globals.js"
|
|
3
4
|
|
|
4
|
-
export { latest, sideEffectsEnabled }
|
|
5
|
+
export { noop, latest, composeRefs, setRef, sideEffectsEnabled }
|
|
6
|
+
|
|
7
|
+
const noop = Object.freeze(() => {})
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
10
|
* This is a no-op in production. It is used to get the latest
|
|
@@ -17,6 +20,31 @@ function latest<T extends Exclude<object, null>>(thing: T): T {
|
|
|
17
20
|
return tgt
|
|
18
21
|
}
|
|
19
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Composes multiple refs into a single ref callback.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
function composeRefs<T>(...refs: Array<Kiru.Ref<T>>): Kiru.RefCallback<T> {
|
|
28
|
+
return (value: T) => {
|
|
29
|
+
refs.forEach((ref) => setRef(ref, value))
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Sets the value of a ref.
|
|
35
|
+
*/
|
|
36
|
+
function setRef<T>(ref: Kiru.Ref<T>, value: T): void {
|
|
37
|
+
if (typeof ref === "function") {
|
|
38
|
+
ref(value)
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
if (Signal.isSignal(ref)) {
|
|
42
|
+
ref.value = value
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
ref.current = value
|
|
46
|
+
}
|
|
47
|
+
|
|
20
48
|
/**
|
|
21
49
|
* Returns false if called during "stream" or "string" render modes.
|
|
22
50
|
*/
|
package/src/utils/vdom.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Signal } from "../signals/base.js"
|
|
2
1
|
import {
|
|
3
2
|
FLAG_DELETION,
|
|
4
3
|
$FRAGMENT,
|
|
@@ -12,10 +11,12 @@ import { KiruError } from "../error.js"
|
|
|
12
11
|
import { node } from "../globals.js"
|
|
13
12
|
import type { AppContext } from "../appContext.js"
|
|
14
13
|
import type { ErrorBoundaryNode } from "../types.utils.js"
|
|
14
|
+
import { isMemoFn } from "../components/memo.js"
|
|
15
15
|
|
|
16
16
|
export {
|
|
17
|
-
|
|
17
|
+
cloneElement,
|
|
18
18
|
isVNodeDeleted,
|
|
19
|
+
isElement,
|
|
19
20
|
isVNode,
|
|
20
21
|
isValidTextChild,
|
|
21
22
|
isExoticType,
|
|
@@ -31,17 +32,16 @@ export {
|
|
|
31
32
|
findParent,
|
|
32
33
|
findParentErrorBoundary,
|
|
33
34
|
assertValidElementProps,
|
|
34
|
-
|
|
35
|
-
isValidElementRefProp,
|
|
35
|
+
normalizeElementKey,
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
function
|
|
38
|
+
function cloneElement(vNode: Kiru.VNode): Kiru.Element {
|
|
39
39
|
const children = vNode.props.children
|
|
40
40
|
let clonedChildren: unknown
|
|
41
41
|
if (isVNode(children)) {
|
|
42
|
-
clonedChildren =
|
|
42
|
+
clonedChildren = cloneElement(children)
|
|
43
43
|
} else if (Array.isArray(children)) {
|
|
44
|
-
clonedChildren = children.map((c) => (isVNode(c) ?
|
|
44
|
+
clonedChildren = children.map((c) => (isVNode(c) ? cloneElement(c) : c))
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
return createElement(vNode.type, { ...vNode.props, children: clonedChildren })
|
|
@@ -55,6 +55,10 @@ function isVNode(thing: unknown): thing is Kiru.VNode {
|
|
|
55
55
|
return typeof thing === "object" && thing !== null && "type" in thing
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
function isElement(thing: unknown): thing is Kiru.Element {
|
|
59
|
+
return typeof thing === "object" && thing !== null && "type" in thing
|
|
60
|
+
}
|
|
61
|
+
|
|
58
62
|
function isValidTextChild(thing: unknown): thing is string | number | bigint {
|
|
59
63
|
return (
|
|
60
64
|
(typeof thing === "string" && thing !== "") ||
|
|
@@ -84,11 +88,7 @@ function isLazy(vNode: Kiru.VNode): boolean {
|
|
|
84
88
|
}
|
|
85
89
|
|
|
86
90
|
function isMemo(vNode: Kiru.VNode): boolean {
|
|
87
|
-
return (
|
|
88
|
-
typeof vNode.type === "function" &&
|
|
89
|
-
"displayName" in vNode.type &&
|
|
90
|
-
vNode.type.displayName === "Kiru.memo"
|
|
91
|
-
)
|
|
91
|
+
return typeof vNode.type === "function" && isMemoFn(vNode.type)
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
function isContextProvider(
|
|
@@ -116,10 +116,11 @@ function getVNodeAppContext(vNode: Kiru.VNode): AppContext | null {
|
|
|
116
116
|
function commitSnapshot(vNode: Kiru.VNode): void {
|
|
117
117
|
const {
|
|
118
118
|
props: { children, ...props },
|
|
119
|
+
key,
|
|
119
120
|
memoizedProps,
|
|
120
121
|
index,
|
|
121
122
|
} = vNode
|
|
122
|
-
vNode.prev = { props, memoizedProps, index }
|
|
123
|
+
vNode.prev = { props, key, memoizedProps, index }
|
|
123
124
|
vNode.flags &= ~(FLAG_UPDATE | FLAG_PLACEMENT | FLAG_DELETION)
|
|
124
125
|
}
|
|
125
126
|
|
|
@@ -187,14 +188,10 @@ function assertValidElementProps(vNode: Kiru.VNode) {
|
|
|
187
188
|
}
|
|
188
189
|
}
|
|
189
190
|
|
|
190
|
-
function
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
return
|
|
196
|
-
typeof thing === "function" ||
|
|
197
|
-
(typeof thing === "object" && !!thing && "current" in thing) ||
|
|
198
|
-
Signal.isSignal(thing)
|
|
199
|
-
)
|
|
191
|
+
function normalizeElementKey(thing: unknown): JSX.ElementKey | null {
|
|
192
|
+
if (thing === undefined) return null
|
|
193
|
+
if (typeof thing === "string" || typeof thing === "number") {
|
|
194
|
+
return thing
|
|
195
|
+
}
|
|
196
|
+
return null
|
|
200
197
|
}
|