kiru 0.52.4 → 0.54.0-preview.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/globals.d.ts +1 -1
- package/dist/globals.d.ts.map +1 -1
- package/dist/globals.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/client/index.d.ts +4 -2
- package/dist/router/client/index.d.ts.map +1 -1
- package/dist/router/client/index.js +49 -11
- package/dist/router/client/index.js.map +1 -1
- package/dist/router/context.d.ts +2 -0
- package/dist/router/context.d.ts.map +1 -1
- package/dist/router/context.js +5 -1
- package/dist/router/context.js.map +1 -1
- package/dist/router/fileRouterController.d.ts +3 -1
- package/dist/router/fileRouterController.d.ts.map +1 -1
- package/dist/router/fileRouterController.js +80 -9
- package/dist/router/fileRouterController.js.map +1 -1
- package/dist/router/globals.d.ts +3 -0
- package/dist/router/globals.d.ts.map +1 -1
- package/dist/router/globals.js +3 -0
- package/dist/router/globals.js.map +1 -1
- package/dist/router/guard.d.ts +17 -0
- package/dist/router/guard.d.ts.map +1 -0
- package/dist/router/guard.js +45 -0
- package/dist/router/guard.js.map +1 -0
- package/dist/router/head.d.ts.map +1 -1
- package/dist/router/head.js +5 -7
- package/dist/router/head.js.map +1 -1
- package/dist/router/index.d.ts +3 -2
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +2 -1
- package/dist/router/index.js.map +1 -1
- package/dist/router/{server → ssg}/index.d.ts +4 -3
- package/dist/router/ssg/index.d.ts.map +1 -0
- package/dist/router/{server → ssg}/index.js +7 -4
- package/dist/router/ssg/index.js.map +1 -0
- package/dist/router/ssr/index.d.ts +20 -0
- package/dist/router/ssr/index.d.ts.map +1 -0
- package/dist/router/ssr/index.js +160 -0
- package/dist/router/ssr/index.js.map +1 -0
- package/dist/router/types.d.ts +37 -4
- package/dist/router/types.d.ts.map +1 -1
- package/dist/router/types.internal.d.ts +4 -0
- package/dist/router/types.internal.d.ts.map +1 -1
- package/dist/router/utils/index.d.ts +9 -4
- package/dist/router/utils/index.d.ts.map +1 -1
- package/dist/router/utils/index.js +38 -6
- package/dist/router/utils/index.js.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/client.d.ts +1 -1
- package/dist/ssr/client.d.ts.map +1 -1
- package/dist/ssr/server.d.ts +1 -2
- package/dist/ssr/server.d.ts.map +1 -1
- package/dist/ssr/server.js +26 -29
- package/dist/ssr/server.js.map +1 -1
- package/dist/types.d.ts +13 -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 +4 -3
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js +8 -4
- 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 +11 -2
- package/dist/utils/runtime.d.ts.map +1 -1
- package/dist/utils/runtime.js +26 -2
- 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 +8 -4
- 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/globals.ts +1 -1
- 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/client/index.ts +100 -14
- package/src/router/context.ts +7 -1
- package/src/router/fileRouterController.ts +137 -8
- package/src/router/globals.ts +4 -0
- package/src/router/guard.ts +72 -0
- package/src/router/head.ts +5 -7
- package/src/router/index.ts +12 -1
- package/src/router/{server → ssg}/index.ts +16 -9
- package/src/router/ssr/index.ts +247 -0
- package/src/router/types.internal.ts +5 -0
- package/src/router/types.ts +48 -4
- package/src/router/utils/index.ts +74 -8
- 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/client.ts +1 -1
- package/src/ssr/server.ts +31 -33
- package/src/types.dom.ts +40 -40
- package/src/types.ts +14 -11
- package/src/types.utils.ts +11 -1
- package/src/utils/format.ts +12 -4
- package/src/utils/index.ts +0 -2
- package/src/utils/promise.ts +26 -0
- package/src/utils/runtime.ts +30 -2
- 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/router/server/index.d.ts.map +0 -1
- package/dist/router/server/index.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/ssr/server.ts
CHANGED
|
@@ -1,71 +1,69 @@
|
|
|
1
|
-
import { Readable } from "node:stream"
|
|
2
1
|
import { Fragment } from "../element.js"
|
|
3
2
|
import { renderMode } from "../globals.js"
|
|
4
|
-
import {
|
|
3
|
+
import { STREAMED_DATA_EVENT } from "../constants.js"
|
|
5
4
|
import { __DEV__ } from "../env.js"
|
|
6
|
-
import {
|
|
5
|
+
import { headlessRender, HeadlessRenderContext } from "../recursiveRender.js"
|
|
7
6
|
|
|
8
|
-
const
|
|
7
|
+
const STREAMED_DATA_SETUP = `
|
|
9
8
|
<script type="text/javascript">
|
|
10
9
|
const d = document,
|
|
11
|
-
m = (window["${
|
|
12
|
-
d.querySelectorAll("[
|
|
10
|
+
m = (window["${STREAMED_DATA_EVENT}"] ??= new Map());
|
|
11
|
+
d.querySelectorAll("[k-data]").forEach((p) => {
|
|
13
12
|
const id = p.getAttribute("id");
|
|
14
13
|
const { data, error } = JSON.parse(p.innerHTML);
|
|
15
14
|
m.set(id, { data, error });
|
|
16
|
-
const event = new CustomEvent("${
|
|
15
|
+
const event = new CustomEvent("${STREAMED_DATA_EVENT}", { detail: { id, data, error } });
|
|
17
16
|
window.dispatchEvent(event);
|
|
18
17
|
p.remove();
|
|
19
18
|
});
|
|
20
19
|
d.currentScript.remove()
|
|
21
20
|
</script>
|
|
22
|
-
|
|
21
|
+
`.replace(/\s+/g, " ")
|
|
23
22
|
|
|
24
23
|
export function renderToReadableStream(element: JSX.Element): {
|
|
25
24
|
immediate: string
|
|
26
|
-
stream:
|
|
25
|
+
stream: ReadableStream | null
|
|
27
26
|
} {
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
const pendingWritePromises: Promise<unknown>[] = []
|
|
27
|
+
const streamPromises = new Set<Kiru.StatefulPromise<unknown>>()
|
|
28
|
+
const dataPromises: Promise<string>[] = []
|
|
29
|
+
let stream: ReadableStream | null = null
|
|
32
30
|
|
|
33
31
|
let immediate = ""
|
|
34
32
|
|
|
35
|
-
const ctx:
|
|
33
|
+
const ctx: HeadlessRenderContext = {
|
|
36
34
|
write: (chunk) => (immediate += chunk),
|
|
37
|
-
|
|
35
|
+
onStreamData(data) {
|
|
38
36
|
for (const promise of data) {
|
|
39
|
-
if (
|
|
40
|
-
|
|
37
|
+
if (streamPromises.has(promise)) continue
|
|
38
|
+
streamPromises.add(promise)
|
|
41
39
|
|
|
42
|
-
const
|
|
40
|
+
const dataPromise = promise
|
|
43
41
|
.then(() => ({ data: promise.value }))
|
|
44
42
|
.catch(() => ({ error: promise.error?.message }))
|
|
45
|
-
.then(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
pendingWritePromises.push(writePromise)
|
|
43
|
+
.then(
|
|
44
|
+
(value, content = JSON.stringify(value)) =>
|
|
45
|
+
`<script id="${promise.id}" k-data type="application/json">${content}</script>`
|
|
46
|
+
)
|
|
47
|
+
dataPromises.push(dataPromise)
|
|
53
48
|
}
|
|
54
49
|
},
|
|
55
50
|
}
|
|
56
51
|
|
|
57
52
|
const prev = renderMode.current
|
|
58
53
|
renderMode.current = "stream"
|
|
59
|
-
|
|
54
|
+
headlessRender(ctx, Fragment({ children: element }), null, 0)
|
|
60
55
|
renderMode.current = prev
|
|
61
56
|
|
|
62
|
-
if (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
57
|
+
if (dataPromises.length > 0) {
|
|
58
|
+
stream = new ReadableStream({
|
|
59
|
+
async pull(controller) {
|
|
60
|
+
for await (const chunk of dataPromises) {
|
|
61
|
+
controller.enqueue(chunk)
|
|
62
|
+
}
|
|
63
|
+
controller.enqueue(STREAMED_DATA_SETUP)
|
|
64
|
+
controller.close()
|
|
65
|
+
},
|
|
66
66
|
})
|
|
67
|
-
} else {
|
|
68
|
-
stream.push(null)
|
|
69
67
|
}
|
|
70
68
|
|
|
71
69
|
return { immediate, stream }
|
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
|
|
|
@@ -117,6 +117,8 @@ declare global {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
namespace Kiru {
|
|
120
|
+
interface RequestContext {}
|
|
121
|
+
|
|
120
122
|
interface CustomEvents {}
|
|
121
123
|
|
|
122
124
|
interface ProviderProps<T> {
|
|
@@ -156,16 +158,13 @@ declare global {
|
|
|
156
158
|
}
|
|
157
159
|
}
|
|
158
160
|
interface RefObject<T> {
|
|
159
|
-
readonly current: T | null
|
|
160
|
-
}
|
|
161
|
-
interface MutableRefObject<T> {
|
|
162
161
|
current: T
|
|
163
162
|
}
|
|
164
163
|
type RefCallback<T> = {
|
|
165
164
|
bivarianceHack(instance: T | null): void
|
|
166
165
|
}["bivarianceHack"]
|
|
167
166
|
|
|
168
|
-
type Ref<T> = RefCallback<T> | RefObject<T>
|
|
167
|
+
type Ref<T> = RefCallback<T> | RefObject<T>
|
|
169
168
|
|
|
170
169
|
interface PromiseState<T> {
|
|
171
170
|
id: string
|
|
@@ -176,6 +175,7 @@ declare global {
|
|
|
176
175
|
|
|
177
176
|
interface StatefulPromise<T> extends Promise<T>, PromiseState<T> {}
|
|
178
177
|
|
|
178
|
+
type HydrationMode = "static" | "dynamic"
|
|
179
179
|
type RenderMode = "dom" | "hydrate" | "string" | "stream"
|
|
180
180
|
|
|
181
181
|
type StateSetter<T> = T | ((prev: T) => T)
|
|
@@ -187,25 +187,27 @@ declare global {
|
|
|
187
187
|
| typeof $CONTEXT_PROVIDER
|
|
188
188
|
| typeof $ERROR_BOUNDARY
|
|
189
189
|
|
|
190
|
-
interface
|
|
191
|
-
app?: AppContext
|
|
192
|
-
dom?: SomeDom
|
|
193
|
-
lastChildDom?: SomeDom
|
|
190
|
+
interface Element {
|
|
194
191
|
type: Function | ExoticSymbol | "#text" | (string & {})
|
|
192
|
+
key: JSX.ElementKey | null
|
|
195
193
|
props: {
|
|
196
194
|
[key: string]: any
|
|
197
195
|
children?: unknown
|
|
198
|
-
key?: JSX.ElementKey
|
|
199
196
|
ref?: Kiru.Ref<unknown>
|
|
200
197
|
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
interface VNode extends Element {
|
|
201
|
+
app?: AppContext
|
|
202
|
+
dom?: SomeDom
|
|
201
203
|
index: number
|
|
202
204
|
depth: number
|
|
205
|
+
flags: number
|
|
203
206
|
parent: VNode | null
|
|
204
207
|
child: VNode | null
|
|
205
208
|
sibling: VNode | null
|
|
206
209
|
prev: VNodeSnapshot | null
|
|
207
210
|
deletions: VNode[] | null
|
|
208
|
-
flags: number
|
|
209
211
|
hooks?: Hook<unknown>[]
|
|
210
212
|
subs?: Set<Function>
|
|
211
213
|
cleanups?: Record<string, Function>
|
|
@@ -223,6 +225,7 @@ declare global {
|
|
|
223
225
|
}
|
|
224
226
|
interface VNodeSnapshot {
|
|
225
227
|
props: Kiru.VNode["props"]
|
|
228
|
+
key: Kiru.VNode["key"]
|
|
226
229
|
memoizedProps: Kiru.VNode["memoizedProps"]
|
|
227
230
|
index: number
|
|
228
231
|
}
|
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
|
@@ -2,6 +2,7 @@ import { unwrap } from "../signals/utils.js"
|
|
|
2
2
|
import { booleanAttributes, snakeCaseAttributes } from "../constants.js"
|
|
3
3
|
|
|
4
4
|
export {
|
|
5
|
+
toArray,
|
|
5
6
|
className,
|
|
6
7
|
encodeHtmlEntities,
|
|
7
8
|
propFilters,
|
|
@@ -20,6 +21,10 @@ const REGEX_DBLQT = /"/g
|
|
|
20
21
|
const REGEX_SLASH = /\//g
|
|
21
22
|
const REGEX_ALPHA_UPPER = /[A-Z]/g
|
|
22
23
|
|
|
24
|
+
function toArray<T>(value: T | T[]): T[] {
|
|
25
|
+
return Array.isArray(value) ? value : [value]
|
|
26
|
+
}
|
|
27
|
+
|
|
23
28
|
function className(...classes: (string | false | null | undefined)[]): string {
|
|
24
29
|
return classes.filter(Boolean).join(" ")
|
|
25
30
|
}
|
|
@@ -34,11 +39,14 @@ function encodeHtmlEntities(text: string): string {
|
|
|
34
39
|
.replace(REGEX_SLASH, "/")
|
|
35
40
|
}
|
|
36
41
|
|
|
42
|
+
const internalProps = new Set(["children", "ref", "key", "innerHTML"])
|
|
37
43
|
const propFilters = {
|
|
38
|
-
|
|
44
|
+
isInternalProp: (
|
|
45
|
+
key: string
|
|
46
|
+
): key is "children" | "ref" | "key" | "innerHTML" => internalProps.has(key),
|
|
39
47
|
isEvent: (key: string) => key.startsWith("on"),
|
|
40
|
-
|
|
41
|
-
!
|
|
48
|
+
isStringRenderableProperty: (key: string) =>
|
|
49
|
+
!internalProps.has(key) && !propFilters.isEvent(key),
|
|
42
50
|
}
|
|
43
51
|
|
|
44
52
|
function propToHtmlAttr(key: string): string {
|
|
@@ -110,7 +118,7 @@ function propsToElementAttributes(props: Record<string, unknown>): string {
|
|
|
110
118
|
if (!!val) attrs.push(`style="${stylePropToString(val)}"`)
|
|
111
119
|
}
|
|
112
120
|
|
|
113
|
-
const keys = Object.keys(rest).filter(propFilters.
|
|
121
|
+
const keys = Object.keys(rest).filter(propFilters.isStringRenderableProperty)
|
|
114
122
|
for (let i = 0; i < keys.length; i++) {
|
|
115
123
|
let k = keys[i]
|
|
116
124
|
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
|
|
@@ -18,7 +21,32 @@ function latest<T extends Exclude<object, null>>(thing: T): T {
|
|
|
18
21
|
}
|
|
19
22
|
|
|
20
23
|
/**
|
|
21
|
-
*
|
|
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
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Returns true if called during 'dom' or 'hydrate' mode.
|
|
22
50
|
*/
|
|
23
51
|
function sideEffectsEnabled(): boolean {
|
|
24
52
|
return renderMode.current === "dom" || renderMode.current === "hydrate"
|
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
|
}
|
package/src/vNode.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { $FRAGMENT } from "./constants.js"
|
|
2
|
+
import { Fragment } from "./element.js"
|
|
3
|
+
|
|
4
|
+
type VNode = Kiru.VNode
|
|
5
|
+
|
|
6
|
+
export function createVNode(
|
|
7
|
+
type: VNode["type"],
|
|
8
|
+
parent: VNode | null = null,
|
|
9
|
+
props: VNode["props"] = {},
|
|
10
|
+
key: VNode["key"] = null,
|
|
11
|
+
index = 0
|
|
12
|
+
): VNode {
|
|
13
|
+
if ((type as any) === Fragment) {
|
|
14
|
+
type = $FRAGMENT
|
|
15
|
+
}
|
|
16
|
+
const depth = parent ? parent.depth + 1 : 0
|
|
17
|
+
return {
|
|
18
|
+
type,
|
|
19
|
+
key,
|
|
20
|
+
props,
|
|
21
|
+
parent,
|
|
22
|
+
index,
|
|
23
|
+
depth,
|
|
24
|
+
flags: 0,
|
|
25
|
+
child: null,
|
|
26
|
+
sibling: null,
|
|
27
|
+
prev: null,
|
|
28
|
+
deletions: null,
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { $SUSPENSE_THROW } from "../constants.js";
|
|
2
|
-
export { Suspense, isSuspenseThrowValue };
|
|
3
|
-
export type { SuspenseProps };
|
|
4
|
-
type StatefulPromiseValues<T extends readonly Kiru.StatefulPromise<unknown>[]> = {
|
|
5
|
-
[I in keyof T]: T[I] extends Kiru.StatefulPromise<infer V> ? V : never;
|
|
6
|
-
};
|
|
7
|
-
type SuspenseChildrenArgs<T extends Kiru.StatefulPromise<any> | Kiru.StatefulPromise<any>[]> = T extends Kiru.StatefulPromise<any>[] ? StatefulPromiseValues<T> : [T extends Kiru.StatefulPromise<infer V> ? V : never];
|
|
8
|
-
interface SuspenseProps<T extends Kiru.StatefulPromise<any> | Kiru.StatefulPromise<any>[]> {
|
|
9
|
-
data: T;
|
|
10
|
-
children: (...data: SuspenseChildrenArgs<T>) => JSX.Element;
|
|
11
|
-
fallback?: JSX.Element;
|
|
12
|
-
}
|
|
13
|
-
declare function Suspense<const T extends Kiru.StatefulPromise<unknown> | Kiru.StatefulPromise<unknown>[]>({ data, children, fallback }: SuspenseProps<T>): JSX.Element;
|
|
14
|
-
interface SuspenseThrowValue {
|
|
15
|
-
[$SUSPENSE_THROW]: {
|
|
16
|
-
fallback?: JSX.Element;
|
|
17
|
-
pending: Kiru.StatefulPromise<unknown>[];
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Returns true if the value was thrown by a Suspense component.
|
|
22
|
-
*/
|
|
23
|
-
declare function isSuspenseThrowValue(value: unknown): value is SuspenseThrowValue;
|
|
24
|
-
//# sourceMappingURL=suspense.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"suspense.d.ts","sourceRoot":"","sources":["../../src/components/suspense.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAKjD,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,CAAA;AACzC,YAAY,EAAE,aAAa,EAAE,CAAA;AAE7B,KAAK,qBAAqB,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,IAC3E;KACG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CACvE,CAAA;AAEH,KAAK,oBAAoB,CACvB,CAAC,SAAS,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,IAC/D,CAAC,SAAS,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,GACrC,qBAAqB,CAAC,CAAC,CAAC,GACxB,CAAC,CAAC,SAAS,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAA;AAEzD,UAAU,aAAa,CACrB,CAAC,SAAS,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE;IAEjE,IAAI,EAAE,CAAC,CAAA;IACP,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,oBAAoB,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAA;IAC3D,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;CACvB;AAED,iBAAS,QAAQ,CACf,KAAK,CAAC,CAAC,SACH,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,GAC7B,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,EACnC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC,eA0B/C;AAED,UAAU,kBAAkB;IAC1B,CAAC,eAAe,CAAC,EAAE;QACjB,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;QACtB,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,CAAA;KACzC,CAAA;CACF;AAED;;GAEG;AACH,iBAAS,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,kBAAkB,CAEzE"}
|