kiru 0.54.3 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{appContext.d.ts → appHandle.d.ts} +4 -4
- package/dist/appHandle.d.ts.map +1 -0
- package/dist/{appContext.js → appHandle.js} +12 -9
- package/dist/appHandle.js.map +1 -0
- package/dist/components/derive.d.ts +10 -8
- package/dist/components/derive.d.ts.map +1 -1
- package/dist/components/derive.js +50 -47
- package/dist/components/derive.js.map +1 -1
- package/dist/components/index.d.ts +0 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +0 -1
- package/dist/components/index.js.map +1 -1
- package/dist/components/lazy.d.ts.map +1 -1
- package/dist/components/lazy.js +5 -4
- package/dist/components/lazy.js.map +1 -1
- package/dist/components/portal.d.ts.map +1 -1
- package/dist/components/portal.js +2 -3
- package/dist/components/portal.js.map +1 -1
- package/dist/components/transition.d.ts +3 -2
- package/dist/components/transition.d.ts.map +1 -1
- package/dist/components/transition.js +29 -26
- package/dist/components/transition.js.map +1 -1
- package/dist/constants.d.ts +1 -5
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +1 -5
- package/dist/constants.js.map +1 -1
- package/dist/context.d.ts +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +25 -19
- package/dist/context.js.map +1 -1
- package/dist/devtools.d.ts +7 -0
- package/dist/devtools.d.ts.map +1 -0
- package/dist/devtools.js +15 -0
- package/dist/devtools.js.map +1 -0
- package/dist/dom.d.ts.map +1 -1
- package/dist/dom.js +25 -58
- package/dist/dom.js.map +1 -1
- package/dist/globalContext.d.ts +15 -16
- package/dist/globalContext.d.ts.map +1 -1
- package/dist/globalContext.js +36 -46
- package/dist/globalContext.js.map +1 -1
- package/dist/globals.d.ts +1 -4
- package/dist/globals.d.ts.map +1 -1
- package/dist/globals.js +1 -4
- package/dist/globals.js.map +1 -1
- package/dist/headlessRender.d.ts +6 -0
- package/dist/headlessRender.d.ts.map +1 -0
- package/dist/{recursiveRender.js → headlessRender.js} +17 -16
- package/dist/headlessRender.js.map +1 -0
- package/dist/hmr.d.ts +5 -7
- package/dist/hmr.d.ts.map +1 -1
- package/dist/hmr.js +27 -32
- package/dist/hmr.js.map +1 -1
- package/dist/hooks/index.d.ts +3 -14
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +3 -14
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/onBeforeMount.d.ts +9 -0
- package/dist/hooks/onBeforeMount.d.ts.map +1 -0
- package/dist/hooks/onBeforeMount.js +12 -0
- package/dist/hooks/onBeforeMount.js.map +1 -0
- package/dist/hooks/onCleanup.d.ts +8 -0
- package/dist/hooks/onCleanup.d.ts.map +1 -0
- package/dist/hooks/onCleanup.js +15 -0
- package/dist/hooks/onCleanup.js.map +1 -0
- package/dist/hooks/onMount.d.ts +9 -0
- package/dist/hooks/onMount.d.ts.map +1 -0
- package/dist/hooks/onMount.js +12 -0
- package/dist/hooks/onMount.js.map +1 -0
- package/dist/hooks/utils.d.ts +2 -62
- package/dist/hooks/utils.d.ts.map +1 -1
- package/dist/hooks/utils.js +22 -144
- package/dist/hooks/utils.js.map +1 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -6
- package/dist/index.js.map +1 -1
- package/dist/profiling.d.ts +15 -14
- package/dist/profiling.d.ts.map +1 -1
- package/dist/profiling.js +9 -4
- package/dist/profiling.js.map +1 -1
- package/dist/reconciler.d.ts.map +1 -1
- package/dist/reconciler.js +12 -25
- package/dist/reconciler.js.map +1 -1
- package/dist/ref.d.ts +4 -0
- package/dist/ref.d.ts.map +1 -0
- package/dist/ref.js +4 -0
- package/dist/ref.js.map +1 -0
- package/dist/renderToString.js +1 -1
- package/dist/renderToString.js.map +1 -1
- package/dist/router/context.d.ts.map +1 -1
- package/dist/router/context.js +1 -2
- package/dist/router/context.js.map +1 -1
- package/dist/router/fileRouter.d.ts +1 -1
- package/dist/router/fileRouter.d.ts.map +1 -1
- package/dist/router/fileRouter.js +17 -11
- package/dist/router/fileRouter.js.map +1 -1
- package/dist/router/fileRouterController.d.ts.map +1 -1
- package/dist/router/fileRouterController.js +68 -55
- package/dist/router/fileRouterController.js.map +1 -1
- package/dist/router/link.d.ts.map +1 -1
- package/dist/router/link.js +19 -23
- package/dist/router/link.js.map +1 -1
- package/dist/router/server/index.d.ts.map +1 -1
- package/dist/router/server/index.js +14 -11
- package/dist/router/server/index.js.map +1 -1
- package/dist/router/types.d.ts +11 -6
- package/dist/router/types.d.ts.map +1 -1
- package/dist/scheduler.d.ts +1 -0
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +65 -52
- package/dist/scheduler.js.map +1 -1
- package/dist/signals/base.d.ts +0 -1
- package/dist/signals/base.d.ts.map +1 -1
- package/dist/signals/base.js +13 -36
- package/dist/signals/base.js.map +1 -1
- package/dist/signals/computed.d.ts +0 -2
- package/dist/signals/computed.d.ts.map +1 -1
- package/dist/signals/computed.js +1 -40
- package/dist/signals/computed.js.map +1 -1
- package/dist/signals/effect.d.ts +15 -14
- package/dist/signals/effect.d.ts.map +1 -1
- package/dist/signals/effect.js +65 -37
- package/dist/signals/effect.js.map +1 -1
- package/dist/signals/globals.d.ts +0 -5
- package/dist/signals/globals.d.ts.map +1 -1
- package/dist/signals/globals.js +0 -6
- package/dist/signals/globals.js.map +1 -1
- package/dist/signals/index.d.ts +4 -4
- package/dist/signals/index.d.ts.map +1 -1
- package/dist/signals/index.js +4 -4
- package/dist/signals/index.js.map +1 -1
- package/dist/signals/{for.d.ts → jsx.d.ts} +8 -1
- package/dist/signals/jsx.d.ts.map +1 -0
- package/dist/signals/{for.js → jsx.js} +4 -1
- package/dist/signals/jsx.js.map +1 -0
- package/dist/signals/tracking.d.ts +23 -0
- package/dist/signals/tracking.d.ts.map +1 -0
- package/dist/signals/tracking.js +51 -0
- package/dist/signals/tracking.js.map +1 -0
- package/dist/signals/types.d.ts +1 -1
- package/dist/signals/types.d.ts.map +1 -1
- package/dist/signals/utils.d.ts +2 -1
- package/dist/signals/utils.d.ts.map +1 -1
- package/dist/signals/utils.js +9 -2
- package/dist/signals/utils.js.map +1 -1
- package/dist/ssr/client.d.ts +3 -3
- package/dist/ssr/client.d.ts.map +1 -1
- package/dist/ssr/client.js.map +1 -1
- package/dist/ssr/server.js +1 -1
- package/dist/ssr/server.js.map +1 -1
- package/dist/statefulPromise.d.ts +22 -0
- package/dist/statefulPromise.d.ts.map +1 -0
- package/dist/statefulPromise.js +94 -0
- package/dist/statefulPromise.js.map +1 -0
- package/dist/types.d.ts +36 -50
- package/dist/types.d.ts.map +1 -1
- package/dist/types.dom.d.ts +4 -7
- package/dist/types.dom.d.ts.map +1 -1
- package/dist/types.utils.d.ts +3 -4
- package/dist/types.utils.d.ts.map +1 -1
- package/dist/utils/vdom.d.ts +8 -6
- package/dist/utils/vdom.d.ts.map +1 -1
- package/dist/utils/vdom.js +32 -9
- package/dist/utils/vdom.js.map +1 -1
- package/dist/viewTransitions.d.ts +7 -0
- package/dist/viewTransitions.d.ts.map +1 -0
- package/dist/viewTransitions.js +71 -0
- package/dist/viewTransitions.js.map +1 -0
- package/package.json +1 -1
- package/src/{appContext.ts → appHandle.ts} +21 -16
- package/src/components/derive.ts +74 -69
- package/src/components/index.ts +0 -1
- package/src/components/lazy.ts +5 -4
- package/src/components/portal.ts +2 -3
- package/src/components/transition.ts +33 -35
- package/src/constants.ts +0 -8
- package/src/context.ts +30 -23
- package/src/devtools.ts +16 -0
- package/src/dom.ts +29 -63
- package/src/globalContext.ts +57 -74
- package/src/globals.ts +1 -5
- package/src/{recursiveRender.ts → headlessRender.ts} +18 -18
- package/src/hmr.ts +29 -38
- package/src/hooks/index.ts +3 -14
- package/src/hooks/onBeforeMount.ts +12 -0
- package/src/hooks/onCleanup.ts +15 -0
- package/src/hooks/onMount.ts +12 -0
- package/src/hooks/utils.ts +28 -238
- package/src/index.ts +14 -6
- package/src/profiling.ts +22 -20
- package/src/reconciler.ts +18 -30
- package/src/ref.ts +6 -0
- package/src/renderToString.ts +1 -1
- package/src/router/context.ts +1 -2
- package/src/router/fileRouter.ts +23 -13
- package/src/router/fileRouterController.ts +72 -64
- package/src/router/link.ts +11 -25
- package/src/router/server/index.ts +24 -13
- package/src/router/types.ts +15 -8
- package/src/scheduler.ts +74 -71
- package/src/signals/base.ts +12 -41
- package/src/signals/computed.ts +1 -62
- package/src/signals/effect.ts +95 -48
- package/src/signals/globals.ts +0 -7
- package/src/signals/index.ts +4 -4
- package/src/signals/{for.ts → jsx.ts} +10 -0
- package/src/signals/tracking.ts +69 -0
- package/src/signals/types.ts +1 -1
- package/src/signals/utils.ts +9 -1
- package/src/ssr/client.ts +4 -4
- package/src/ssr/server.ts +2 -2
- package/src/statefulPromise.ts +136 -0
- package/src/types.dom.ts +4 -8
- package/src/types.ts +45 -58
- package/src/types.utils.ts +3 -4
- package/src/utils/vdom.ts +44 -15
- package/src/viewTransitions.ts +88 -0
- package/dist/appContext.d.ts.map +0 -1
- package/dist/appContext.js.map +0 -1
- package/dist/components/memo.d.ts +0 -10
- package/dist/components/memo.d.ts.map +0 -1
- package/dist/components/memo.js +0 -23
- package/dist/components/memo.js.map +0 -1
- package/dist/form/index.d.ts +0 -4
- package/dist/form/index.d.ts.map +0 -1
- package/dist/form/index.js +0 -518
- package/dist/form/index.js.map +0 -1
- package/dist/form/types.d.ts +0 -122
- package/dist/form/types.d.ts.map +0 -1
- package/dist/form/types.js +0 -2
- package/dist/form/types.js.map +0 -1
- package/dist/form/utils.d.ts +0 -3
- package/dist/form/utils.d.ts.map +0 -1
- package/dist/form/utils.js +0 -16
- package/dist/form/utils.js.map +0 -1
- package/dist/hooks/useAsync.d.ts +0 -18
- package/dist/hooks/useAsync.d.ts.map +0 -1
- package/dist/hooks/useAsync.js +0 -96
- package/dist/hooks/useAsync.js.map +0 -1
- package/dist/hooks/useCallback.d.ts +0 -7
- package/dist/hooks/useCallback.d.ts.map +0 -1
- package/dist/hooks/useCallback.js +0 -30
- package/dist/hooks/useCallback.js.map +0 -1
- package/dist/hooks/useContext.d.ts +0 -7
- package/dist/hooks/useContext.d.ts.map +0 -1
- package/dist/hooks/useContext.js +0 -59
- package/dist/hooks/useContext.js.map +0 -1
- package/dist/hooks/useEffect.d.ts +0 -8
- package/dist/hooks/useEffect.d.ts.map +0 -1
- package/dist/hooks/useEffect.js +0 -34
- package/dist/hooks/useEffect.js.map +0 -1
- package/dist/hooks/useEffectEvent.d.ts +0 -8
- package/dist/hooks/useEffectEvent.d.ts.map +0 -1
- package/dist/hooks/useEffectEvent.js +0 -23
- package/dist/hooks/useEffectEvent.js.map +0 -1
- package/dist/hooks/useId.d.ts +0 -8
- package/dist/hooks/useId.d.ts.map +0 -1
- package/dist/hooks/useId.js +0 -35
- package/dist/hooks/useId.js.map +0 -1
- package/dist/hooks/useLayoutEffect.d.ts +0 -8
- package/dist/hooks/useLayoutEffect.d.ts.map +0 -1
- package/dist/hooks/useLayoutEffect.js +0 -34
- package/dist/hooks/useLayoutEffect.js.map +0 -1
- package/dist/hooks/useMemo.d.ts +0 -8
- package/dist/hooks/useMemo.d.ts.map +0 -1
- package/dist/hooks/useMemo.js +0 -31
- package/dist/hooks/useMemo.js.map +0 -1
- package/dist/hooks/usePromise.d.ts +0 -8
- package/dist/hooks/usePromise.d.ts.map +0 -1
- package/dist/hooks/usePromise.js +0 -90
- package/dist/hooks/usePromise.js.map +0 -1
- package/dist/hooks/useReducer.d.ts +0 -7
- package/dist/hooks/useReducer.d.ts.map +0 -1
- package/dist/hooks/useReducer.js +0 -44
- package/dist/hooks/useReducer.js.map +0 -1
- package/dist/hooks/useRef.d.ts +0 -10
- package/dist/hooks/useRef.d.ts.map +0 -1
- package/dist/hooks/useRef.js +0 -29
- package/dist/hooks/useRef.js.map +0 -1
- package/dist/hooks/useState.d.ts +0 -7
- package/dist/hooks/useState.d.ts.map +0 -1
- package/dist/hooks/useState.js +0 -54
- package/dist/hooks/useState.js.map +0 -1
- package/dist/hooks/useSyncExternalStore.d.ts +0 -8
- package/dist/hooks/useSyncExternalStore.d.ts.map +0 -1
- package/dist/hooks/useSyncExternalStore.js +0 -50
- package/dist/hooks/useSyncExternalStore.js.map +0 -1
- package/dist/hooks/useViewTransition.d.ts +0 -10
- package/dist/hooks/useViewTransition.d.ts.map +0 -1
- package/dist/hooks/useViewTransition.js +0 -27
- package/dist/hooks/useViewTransition.js.map +0 -1
- package/dist/recursiveRender.d.ts +0 -7
- package/dist/recursiveRender.d.ts.map +0 -1
- package/dist/recursiveRender.js.map +0 -1
- package/dist/signals/for.d.ts.map +0 -1
- package/dist/signals/for.js.map +0 -1
- package/dist/signals/watch.d.ts +0 -21
- package/dist/signals/watch.d.ts.map +0 -1
- package/dist/signals/watch.js +0 -86
- package/dist/signals/watch.js.map +0 -1
- package/dist/store.d.ts +0 -28
- package/dist/store.d.ts.map +0 -1
- package/dist/store.js +0 -166
- package/dist/store.js.map +0 -1
- package/dist/swr.d.ts +0 -63
- package/dist/swr.d.ts.map +0 -1
- package/dist/swr.js +0 -236
- package/dist/swr.js.map +0 -1
- package/dist/utils/promise.d.ts +0 -16
- package/dist/utils/promise.d.ts.map +0 -1
- package/dist/utils/promise.js +0 -14
- package/dist/utils/promise.js.map +0 -1
- package/src/components/memo.ts +0 -39
- package/src/form/index.ts +0 -676
- package/src/form/types.ts +0 -262
- package/src/form/utils.ts +0 -19
- package/src/hooks/useAsync.ts +0 -121
- package/src/hooks/useCallback.ts +0 -32
- package/src/hooks/useContext.ts +0 -79
- package/src/hooks/useEffect.ts +0 -40
- package/src/hooks/useEffectEvent.ts +0 -24
- package/src/hooks/useId.ts +0 -42
- package/src/hooks/useLayoutEffect.ts +0 -43
- package/src/hooks/useMemo.ts +0 -34
- package/src/hooks/usePromise.ts +0 -126
- package/src/hooks/useReducer.ts +0 -50
- package/src/hooks/useRef.ts +0 -41
- package/src/hooks/useState.ts +0 -62
- package/src/hooks/useSyncExternalStore.ts +0 -59
- package/src/hooks/useViewTransition.ts +0 -25
- package/src/signals/watch.ts +0 -139
- package/src/store.ts +0 -245
- package/src/swr.ts +0 -351
- package/src/utils/promise.ts +0 -26
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { queueSetupEffect } from "./utils.js"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Registers a callback that runs after the component is first mounted to the DOM, but before the DOM is painted.
|
|
5
|
+
* Optionally returns a cleanup function that will run when the component unmounts.
|
|
6
|
+
* Intended for use during component setup when the component returns a render function.
|
|
7
|
+
*
|
|
8
|
+
* @see https://kirujs.dev/docs/hooks/onBeforeMount
|
|
9
|
+
*/
|
|
10
|
+
export function onBeforeMount(fn: () => (() => void) | void): void {
|
|
11
|
+
queueSetupEffect(fn, { immediate: true })
|
|
12
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { node } from "../globals.js"
|
|
2
|
+
import { generateRandomID, registerVNodeCleanup } from "../utils/index.js"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Registers a cleanup function that runs when the component unmounts.
|
|
6
|
+
* Intended for use during component setup when the component returns a render function.
|
|
7
|
+
*
|
|
8
|
+
* @see https://kirujs.dev/docs/hooks/onCleanup
|
|
9
|
+
*/
|
|
10
|
+
export function onCleanup(fn: () => void): void {
|
|
11
|
+
const vNode = node.current!
|
|
12
|
+
if (!vNode)
|
|
13
|
+
throw new Error("Cannot queue cleanup effect outside of a component")
|
|
14
|
+
registerVNodeCleanup(vNode, generateRandomID(10), fn)
|
|
15
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { queueSetupEffect } from "./utils.js"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Registers a callback that runs after the component is first mounted to the DOM.
|
|
5
|
+
* Optionally returns a cleanup function that will run when the component unmounts.
|
|
6
|
+
* Intended for use during component setup when the component returns a render function.
|
|
7
|
+
*
|
|
8
|
+
* @see https://kirujs.dev/docs/hooks/onMount
|
|
9
|
+
*/
|
|
10
|
+
export function onMount(fn: () => (() => void) | void): void {
|
|
11
|
+
queueSetupEffect(fn)
|
|
12
|
+
}
|
package/src/hooks/utils.ts
CHANGED
|
@@ -1,242 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
* **dev only - this is a no-op in production.**
|
|
29
|
-
*
|
|
30
|
-
* Used to create 'groups' of hooks in the devtools.
|
|
31
|
-
* Useful for debugging and profiling.
|
|
32
|
-
*/
|
|
33
|
-
const useHookDebugGroup = (name: string, action: HookDebugGroupAction) => {
|
|
34
|
-
if (__DEV__) {
|
|
35
|
-
return useHook(
|
|
36
|
-
"devtools:useHookDebugGroup",
|
|
37
|
-
{ displayName: name, action },
|
|
38
|
-
noop
|
|
39
|
-
)
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Used obtain an 'requestUpdate' function for the current component.
|
|
45
|
-
*/
|
|
46
|
-
const useRequestUpdate = () => {
|
|
47
|
-
const vNode = getVNodeOrError("useRequestUpdate")
|
|
48
|
-
return () => requestUpdate(vNode)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Used to obtain the 'VNode' for the current component.
|
|
53
|
-
*/
|
|
54
|
-
const useVNode = () => {
|
|
55
|
-
return getVNodeOrError("useVNode")
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
type HookCallbackContext<T> = {
|
|
59
|
-
/**
|
|
60
|
-
* The current state of the hook
|
|
61
|
-
*/
|
|
62
|
-
hook: HookState<T>
|
|
63
|
-
/**
|
|
64
|
-
* Indicates if this is the first time the hook has been initialized
|
|
65
|
-
*/
|
|
66
|
-
isInit: boolean
|
|
67
|
-
/**
|
|
68
|
-
* Dev mode only - indicates if the hook is being run as a result of a HMR update.
|
|
69
|
-
* This is the time to clean up the previous version of the hook if necessary, ie. initial arguments changed.
|
|
70
|
-
*/
|
|
71
|
-
isHMR?: boolean
|
|
72
|
-
/**
|
|
73
|
-
* Queues the current component to be re-rendered
|
|
74
|
-
*/
|
|
75
|
-
update: () => void
|
|
76
|
-
/**
|
|
77
|
-
* Queues an effect to be run, either immediately or on the next render
|
|
78
|
-
*/
|
|
79
|
-
queueEffect: (callback: Function, opts?: { immediate?: boolean }) => void
|
|
80
|
-
/**
|
|
81
|
-
* The VNode associated with the current component
|
|
82
|
-
*/
|
|
83
|
-
vNode: Kiru.VNode
|
|
84
|
-
/**
|
|
85
|
-
* The index of the current hook.
|
|
86
|
-
* You can count on this being stable across renders,
|
|
87
|
-
* and unique across separate hooks in the same component.
|
|
88
|
-
*/
|
|
89
|
-
index: number
|
|
90
|
-
}
|
|
91
|
-
type HookCallback<T> = (state: HookCallbackContext<T>) => any
|
|
92
|
-
|
|
93
|
-
let currentHookName: string | null = null
|
|
94
|
-
const nestedHookWarnings = new Set<string>()
|
|
95
|
-
|
|
96
|
-
function useHook<
|
|
97
|
-
T extends () => Record<string, unknown>,
|
|
98
|
-
U extends HookCallback<ReturnType<T>>
|
|
99
|
-
>(hookName: string, hookInitializer: T, callback: U): ReturnType<U>
|
|
100
|
-
|
|
101
|
-
function useHook<T extends Record<string, unknown>, U extends HookCallback<T>>(
|
|
102
|
-
hookName: string,
|
|
103
|
-
hookData: T,
|
|
104
|
-
callback: U
|
|
105
|
-
): ReturnType<U>
|
|
106
|
-
|
|
107
|
-
function useHook<
|
|
108
|
-
T,
|
|
109
|
-
U extends T extends () => Record<string, unknown>
|
|
110
|
-
? HookCallback<ReturnType<T>>
|
|
111
|
-
: HookCallback<T>
|
|
112
|
-
>(
|
|
113
|
-
hookName: string,
|
|
114
|
-
hookDataOrInitializer: HookState<T> | (() => HookState<T>),
|
|
115
|
-
callback: U
|
|
116
|
-
): ReturnType<U> {
|
|
117
|
-
const vNode = getVNodeOrError(hookName)
|
|
118
|
-
|
|
119
|
-
if (
|
|
120
|
-
__DEV__ &&
|
|
121
|
-
currentHookName !== null &&
|
|
122
|
-
!nestedHookWarnings.has(hookName + currentHookName)
|
|
123
|
-
) {
|
|
124
|
-
nestedHookWarnings.add(hookName + currentHookName)
|
|
125
|
-
throw new KiruError({
|
|
126
|
-
message: `Nested primitive "useHook" calls are not supported. "${hookName}" was called inside "${currentHookName}". Strange will most certainly happen.`,
|
|
127
|
-
vNode,
|
|
128
|
-
})
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const queueEffect = (callback: Function, opts?: { immediate?: boolean }) => {
|
|
132
|
-
if (opts?.immediate) {
|
|
133
|
-
;(vNode.immediateEffects ??= []).push(callback)
|
|
134
|
-
return
|
|
1
|
+
import { node } from "../globals.js"
|
|
2
|
+
import { sideEffectsEnabled } from "../utils/index.js"
|
|
3
|
+
|
|
4
|
+
export function queueSetupEffect(
|
|
5
|
+
effect: Kiru.LifecycleHookCallback,
|
|
6
|
+
opts?: { immediate?: boolean }
|
|
7
|
+
): void {
|
|
8
|
+
if (!sideEffectsEnabled()) return
|
|
9
|
+
const vNode = node.current!
|
|
10
|
+
if (!vNode)
|
|
11
|
+
throw new Error("Cannot queue setup effect outside of a component")
|
|
12
|
+
|
|
13
|
+
const hooks = (vNode.hooks ??= {
|
|
14
|
+
pre: [],
|
|
15
|
+
preCleanups: [],
|
|
16
|
+
post: [],
|
|
17
|
+
postCleanups: [],
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const [bag, cleanups] = opts?.immediate
|
|
21
|
+
? [hooks.pre, hooks.preCleanups]
|
|
22
|
+
: [hooks.post, hooks.postCleanups]
|
|
23
|
+
|
|
24
|
+
const wrapped = () => {
|
|
25
|
+
const ret = effect()
|
|
26
|
+
if (typeof ret === "function") {
|
|
27
|
+
cleanups.push(ret)
|
|
135
28
|
}
|
|
136
|
-
;(vNode.effects ??= []).push(callback)
|
|
137
29
|
}
|
|
138
30
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
let oldHook = vNode.hooks?.at(index) as HookState<T> | undefined
|
|
142
|
-
|
|
143
|
-
if (__DEV__) {
|
|
144
|
-
currentHookName = hookName
|
|
145
|
-
|
|
146
|
-
vNode.hooks ??= []
|
|
147
|
-
vNode.hookSig ??= []
|
|
148
|
-
|
|
149
|
-
if (!vNode.hookSig[index]) {
|
|
150
|
-
vNode.hookSig[index] = hookName
|
|
151
|
-
} else {
|
|
152
|
-
if (vNode.hookSig[index] !== hookName) {
|
|
153
|
-
console.warn(
|
|
154
|
-
`[kiru]: hooks must be called in the same order. Hook "${hookName}" was called in place of "${vNode.hookSig[index]}". Strange things may happen.`
|
|
155
|
-
)
|
|
156
|
-
oldHook?.cleanup?.()
|
|
157
|
-
vNode.hooks.length = index
|
|
158
|
-
vNode.hookSig.length = index
|
|
159
|
-
oldHook = undefined
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
let hook: HookState<T>
|
|
164
|
-
if (!oldHook) {
|
|
165
|
-
hook =
|
|
166
|
-
typeof hookDataOrInitializer === "function"
|
|
167
|
-
? hookDataOrInitializer()
|
|
168
|
-
: { ...hookDataOrInitializer }
|
|
169
|
-
hook.name = hookName
|
|
170
|
-
} else {
|
|
171
|
-
hook = oldHook
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
vNode.hooks[index] = hook
|
|
175
|
-
|
|
176
|
-
try {
|
|
177
|
-
const res = (callback as HookCallback<T>)({
|
|
178
|
-
hook,
|
|
179
|
-
isInit: !oldHook,
|
|
180
|
-
isHMR: isHmrUpdate(),
|
|
181
|
-
update: () => requestUpdate(vNode),
|
|
182
|
-
queueEffect,
|
|
183
|
-
vNode,
|
|
184
|
-
index,
|
|
185
|
-
})
|
|
186
|
-
return res
|
|
187
|
-
} catch (error) {
|
|
188
|
-
throw error
|
|
189
|
-
} finally {
|
|
190
|
-
currentHookName = null
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
try {
|
|
195
|
-
const hook: HookState<T> =
|
|
196
|
-
oldHook ??
|
|
197
|
-
(typeof hookDataOrInitializer === "function"
|
|
198
|
-
? hookDataOrInitializer()
|
|
199
|
-
: { ...hookDataOrInitializer })
|
|
200
|
-
|
|
201
|
-
vNode.hooks ??= []
|
|
202
|
-
vNode.hooks[index] = hook
|
|
203
|
-
|
|
204
|
-
const res = (callback as HookCallback<T>)({
|
|
205
|
-
hook,
|
|
206
|
-
isInit: !oldHook,
|
|
207
|
-
update: () => requestUpdate(vNode),
|
|
208
|
-
queueEffect,
|
|
209
|
-
vNode,
|
|
210
|
-
index,
|
|
211
|
-
})
|
|
212
|
-
return res
|
|
213
|
-
} catch (error) {
|
|
214
|
-
throw error
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function getVNodeOrError(hookName: string) {
|
|
219
|
-
const vNode = node.current
|
|
220
|
-
if (!vNode) {
|
|
221
|
-
throw new KiruError(
|
|
222
|
-
`Hook "${hookName}" must be used at the top level of a component or inside another composite hook.`
|
|
223
|
-
)
|
|
224
|
-
}
|
|
225
|
-
return vNode
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function cleanupHook(hook: { cleanup?: () => void }) {
|
|
229
|
-
if (hook.cleanup) {
|
|
230
|
-
hook.cleanup()
|
|
231
|
-
hook.cleanup = undefined
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
function depsRequireChange(a?: unknown[], b?: unknown[]) {
|
|
236
|
-
return (
|
|
237
|
-
a === undefined ||
|
|
238
|
-
b === undefined ||
|
|
239
|
-
a.length !== b.length ||
|
|
240
|
-
(a.length > 0 && b.some((dep, i) => !Object.is(dep, a[i])))
|
|
241
|
-
)
|
|
31
|
+
bag.push(wrapped)
|
|
242
32
|
}
|
package/src/index.ts
CHANGED
|
@@ -3,18 +3,26 @@ import { createKiruGlobalContext } from "./globalContext.js"
|
|
|
3
3
|
export type * from "./types"
|
|
4
4
|
export * from "./signals/index.js"
|
|
5
5
|
export * from "./action.js"
|
|
6
|
-
export * from "./
|
|
6
|
+
export * from "./appHandle.js"
|
|
7
|
+
export * from "./components/index.js"
|
|
7
8
|
export * from "./context.js"
|
|
8
9
|
export * from "./customEvents.js"
|
|
10
|
+
export * from "./devtools.js"
|
|
9
11
|
export * from "./element.js"
|
|
10
12
|
export * from "./error.js"
|
|
11
13
|
export * from "./hooks/index.js"
|
|
12
|
-
export
|
|
14
|
+
export type { ProfilingEvent, AppStats } from "./profiling.js"
|
|
13
15
|
export * from "./renderToString.js"
|
|
14
|
-
export
|
|
15
|
-
export
|
|
16
|
+
export * from "./ref.js"
|
|
17
|
+
export {
|
|
18
|
+
nextIdle,
|
|
19
|
+
flushSync,
|
|
20
|
+
requestUpdate,
|
|
21
|
+
useRequestUpdate,
|
|
22
|
+
} from "./scheduler.js"
|
|
23
|
+
export * from "./statefulPromise.js"
|
|
24
|
+
export * from "./viewTransitions.js"
|
|
16
25
|
|
|
17
|
-
|
|
18
|
-
if ("window" in globalThis && !globalThis.__KIRU_DEVTOOLS__) {
|
|
26
|
+
if ("window" in globalThis) {
|
|
19
27
|
globalThis.window.__kiru ??= createKiruGlobalContext()
|
|
20
28
|
}
|
package/src/profiling.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AppHandle } from "./appHandle"
|
|
2
2
|
|
|
3
3
|
const MAX_TICKS = 100
|
|
4
4
|
|
|
@@ -13,27 +13,25 @@ const ProfilingEvents = [
|
|
|
13
13
|
] as const
|
|
14
14
|
|
|
15
15
|
export type ProfilingEvent = (typeof ProfilingEvents)[number]
|
|
16
|
+
export interface AppStats {
|
|
17
|
+
timestamps: TickTS[]
|
|
18
|
+
mountDuration: number
|
|
19
|
+
totalTicks: number
|
|
20
|
+
}
|
|
16
21
|
|
|
17
22
|
interface TickTS {
|
|
18
23
|
start: number
|
|
19
24
|
end: number
|
|
20
25
|
}
|
|
21
26
|
|
|
22
|
-
type ProfilingEventListener = (app:
|
|
27
|
+
type ProfilingEventListener = (app: AppHandle) => void
|
|
23
28
|
|
|
24
29
|
export function createProfilingContext() {
|
|
25
30
|
const eventListeners = new Map<ProfilingEvent, Set<ProfilingEventListener>>()
|
|
26
|
-
const appStats: Map<
|
|
27
|
-
AppContext,
|
|
28
|
-
{
|
|
29
|
-
timestamps: TickTS[]
|
|
30
|
-
mountDuration: number
|
|
31
|
-
totalTicks: number
|
|
32
|
-
}
|
|
33
|
-
> = new Map()
|
|
31
|
+
const appStats: Map<AppHandle, AppStats> = new Map()
|
|
34
32
|
return {
|
|
35
33
|
appStats,
|
|
36
|
-
emit: (event: ProfilingEvent, app:
|
|
34
|
+
emit: (event: ProfilingEvent, app: AppHandle) => {
|
|
37
35
|
eventListeners.get(event)?.forEach((listener) => listener(app))
|
|
38
36
|
},
|
|
39
37
|
addEventListener: (
|
|
@@ -52,23 +50,28 @@ export function createProfilingContext() {
|
|
|
52
50
|
if (!eventListeners.has(event)) return
|
|
53
51
|
eventListeners.get(event)!.delete(listener)
|
|
54
52
|
},
|
|
55
|
-
mountDuration: (app:
|
|
53
|
+
mountDuration: (app: AppHandle) => {
|
|
56
54
|
const stats = appStats.get(app)
|
|
57
55
|
if (!stats) return 0
|
|
58
56
|
return stats.mountDuration
|
|
59
57
|
},
|
|
60
|
-
totalTicks: (app:
|
|
58
|
+
totalTicks: (app: AppHandle) => {
|
|
61
59
|
const stats = appStats.get(app)
|
|
62
60
|
if (!stats) return 0
|
|
63
61
|
return stats.totalTicks
|
|
64
62
|
},
|
|
65
|
-
lastTickDuration: (app:
|
|
63
|
+
lastTickDuration: (app: AppHandle) => {
|
|
66
64
|
const stats = appStats.get(app)
|
|
67
|
-
if (!stats) return
|
|
68
|
-
|
|
65
|
+
if (!stats) return Infinity
|
|
66
|
+
let last = stats.timestamps[stats.timestamps.length - 1]
|
|
67
|
+
if (!last) return Infinity
|
|
68
|
+
if (last.end === Infinity) {
|
|
69
|
+
last = stats.timestamps[stats.timestamps.length - 2]
|
|
70
|
+
}
|
|
71
|
+
if (!last) return Infinity
|
|
69
72
|
return last.end - last.start
|
|
70
73
|
},
|
|
71
|
-
averageTickDuration: (app:
|
|
74
|
+
averageTickDuration: (app: AppHandle) => {
|
|
72
75
|
const stats = appStats.get(app)
|
|
73
76
|
if (!stats) return 0
|
|
74
77
|
const completeTicks = stats.timestamps.filter((ts) => ts.end !== Infinity)
|
|
@@ -77,7 +80,7 @@ export function createProfilingContext() {
|
|
|
77
80
|
completeTicks.length
|
|
78
81
|
)
|
|
79
82
|
},
|
|
80
|
-
beginTick: (app:
|
|
83
|
+
beginTick: (app: AppHandle) => {
|
|
81
84
|
if (!appStats.has(app)) {
|
|
82
85
|
appStats.set(app, {
|
|
83
86
|
mountDuration: Infinity,
|
|
@@ -89,8 +92,7 @@ export function createProfilingContext() {
|
|
|
89
92
|
stats.totalTicks++
|
|
90
93
|
stats.timestamps.push({ start: performance.now(), end: Infinity })
|
|
91
94
|
},
|
|
92
|
-
endTick: (app:
|
|
93
|
-
if (!appStats.has(app)) return
|
|
95
|
+
endTick: (app: AppHandle) => {
|
|
94
96
|
const stats = appStats.get(app)!
|
|
95
97
|
|
|
96
98
|
const last = stats.timestamps[stats.timestamps.length - 1]
|
package/src/reconciler.ts
CHANGED
|
@@ -1,31 +1,26 @@
|
|
|
1
|
+
import { $FRAGMENT, FLAG_PLACEMENT, FLAG_UPDATE } from "./constants.js"
|
|
1
2
|
import {
|
|
2
|
-
|
|
3
|
-
FLAG_MEMO,
|
|
4
|
-
FLAG_PLACEMENT,
|
|
5
|
-
FLAG_UPDATE,
|
|
6
|
-
} from "./constants.js"
|
|
7
|
-
import {
|
|
8
|
-
getVNodeAppContext,
|
|
3
|
+
getVNodeApp,
|
|
9
4
|
isElement,
|
|
10
5
|
isValidTextChild,
|
|
11
6
|
latest,
|
|
7
|
+
propsChanged,
|
|
12
8
|
} from "./utils/index.js"
|
|
13
9
|
import { Signal } from "./signals/base.js"
|
|
14
10
|
import { __DEV__ } from "./env.js"
|
|
15
|
-
import type {
|
|
16
|
-
import { isMemoFn } from "./components/memo.js"
|
|
11
|
+
import type { AppHandle } from "./appHandle.js"
|
|
17
12
|
import { createVNode as createBaseVNode } from "./vNode.js"
|
|
18
13
|
|
|
19
14
|
type VNode = Kiru.VNode
|
|
20
15
|
type KElement = Kiru.Element
|
|
21
|
-
let
|
|
16
|
+
let app: AppHandle
|
|
22
17
|
|
|
23
18
|
export function reconcileChildren(
|
|
24
19
|
parent: VNode,
|
|
25
20
|
children: unknown
|
|
26
21
|
): VNode | null {
|
|
27
22
|
if (__DEV__) {
|
|
28
|
-
|
|
23
|
+
app = getVNodeApp(parent)!
|
|
29
24
|
}
|
|
30
25
|
if (Array.isArray(children)) {
|
|
31
26
|
if (__DEV__) {
|
|
@@ -238,7 +233,7 @@ function updateNode(parent: VNode, oldChild: VNode | null, newChild: KElement) {
|
|
|
238
233
|
oldChild.index = 0
|
|
239
234
|
oldChild.sibling = null
|
|
240
235
|
if (typeof type === "string") {
|
|
241
|
-
if (
|
|
236
|
+
if (domNodePropsChanged(oldChild.props, props)) {
|
|
242
237
|
oldChild.flags |= FLAG_UPDATE
|
|
243
238
|
}
|
|
244
239
|
} else {
|
|
@@ -344,7 +339,7 @@ function updateFromMap(
|
|
|
344
339
|
dev_emitUpdateNode()
|
|
345
340
|
}
|
|
346
341
|
if (typeof type === "string") {
|
|
347
|
-
if (
|
|
342
|
+
if (domNodePropsChanged(oldChild.props, props)) {
|
|
348
343
|
oldChild.flags |= FLAG_UPDATE
|
|
349
344
|
}
|
|
350
345
|
} else {
|
|
@@ -380,20 +375,9 @@ function updateFromMap(
|
|
|
380
375
|
return null
|
|
381
376
|
}
|
|
382
377
|
|
|
383
|
-
function propsChanged(oldProps: VNode["props"], newProps: VNode["props"]) {
|
|
384
|
-
const aKeys = Object.keys(oldProps)
|
|
385
|
-
const bKeys = Object.keys(newProps)
|
|
386
|
-
if (aKeys.length !== bKeys.length) return true
|
|
387
|
-
for (let key of aKeys) {
|
|
388
|
-
if (key === "children" || key === "key") continue
|
|
389
|
-
if (oldProps[key] !== newProps[key]) return true
|
|
390
|
-
}
|
|
391
|
-
return false
|
|
392
|
-
}
|
|
393
|
-
|
|
394
378
|
function dev_emitUpdateNode() {
|
|
395
379
|
if (!("window" in globalThis)) return
|
|
396
|
-
window.__kiru.profilingContext?.emit("updateNode",
|
|
380
|
+
window.__kiru.profilingContext?.emit("updateNode", app)
|
|
397
381
|
}
|
|
398
382
|
|
|
399
383
|
const $LIST_CHILD = Symbol("kiru:marked-list-child")
|
|
@@ -495,12 +479,16 @@ function createVNode(
|
|
|
495
479
|
const node = createBaseVNode(type, parent, props, key, index)
|
|
496
480
|
node.flags |= FLAG_PLACEMENT
|
|
497
481
|
|
|
498
|
-
if (typeof type === "function" && isMemoFn(type)) {
|
|
499
|
-
node.flags |= FLAG_MEMO
|
|
500
|
-
}
|
|
501
|
-
|
|
502
482
|
if (__DEV__ && "window" in globalThis) {
|
|
503
|
-
window.__kiru.profilingContext?.emit("createNode",
|
|
483
|
+
window.__kiru.profilingContext?.emit("createNode", app)
|
|
504
484
|
}
|
|
505
485
|
return node
|
|
506
486
|
}
|
|
487
|
+
|
|
488
|
+
const IGNORED_DOM_NODE_PROPS = ["children", "key"]
|
|
489
|
+
function domNodePropsChanged(
|
|
490
|
+
oldProps: Kiru.VNode["props"],
|
|
491
|
+
newProps: Kiru.VNode["props"]
|
|
492
|
+
) {
|
|
493
|
+
return propsChanged(oldProps, newProps, IGNORED_DOM_NODE_PROPS)
|
|
494
|
+
}
|
package/src/ref.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export function ref<T>(initialValue: T): Kiru.RefObject<T>
|
|
2
|
+
export function ref<T>(initialValue: T | null): Kiru.RefObject<T | null>
|
|
3
|
+
export function ref<T = undefined>(): Kiru.RefObject<T | undefined>
|
|
4
|
+
export function ref<T>(initialValue?: T | null) {
|
|
5
|
+
return { current: initialValue }
|
|
6
|
+
}
|
package/src/renderToString.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { renderMode } from "./globals.js"
|
|
2
2
|
import { Fragment } from "./element.js"
|
|
3
|
-
import { headlessRender, HeadlessRenderContext } from "./
|
|
3
|
+
import { headlessRender, HeadlessRenderContext } from "./headlessRender.js"
|
|
4
4
|
|
|
5
5
|
export function renderToString(element: JSX.Element) {
|
|
6
6
|
const prev = renderMode.current
|
package/src/router/context.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { createContext } from "../context.js"
|
|
1
|
+
import { createContext, useContext } from "../context.js"
|
|
2
2
|
import { __DEV__ } from "../env.js"
|
|
3
|
-
import { useContext } from "../hooks/index.js"
|
|
4
3
|
import type { RouteQuery, RouterState } from "./types.js"
|
|
5
4
|
|
|
6
5
|
export interface ReloadOptions {
|
package/src/router/fileRouter.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createElement } from "../element.js"
|
|
2
|
-
import { useState, useEffect } from "../hooks/index.js"
|
|
3
2
|
import { RouterContext } from "./context.js"
|
|
4
3
|
import { FileRouterController } from "./fileRouterController.js"
|
|
5
4
|
import type { FileRouterConfig } from "./types.js"
|
|
6
5
|
import { fileRouterInstance } from "./globals.js"
|
|
6
|
+
import { onCleanup } from "../hooks/onCleanup.js"
|
|
7
7
|
|
|
8
8
|
export interface FileRouterProps {
|
|
9
9
|
/**
|
|
@@ -24,18 +24,28 @@ export interface FileRouterProps {
|
|
|
24
24
|
config: FileRouterConfig
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
router.init(config)
|
|
32
|
-
return router
|
|
33
|
-
})
|
|
34
|
-
useEffect(() => () => controller.dispose(), [controller])
|
|
27
|
+
export const FileRouter: Kiru.FC<FileRouterProps> = ({ config }) => {
|
|
28
|
+
fileRouterInstance.current?.dispose()
|
|
29
|
+
let router = (fileRouterInstance.current = new FileRouterController())
|
|
30
|
+
let configStr = ""
|
|
35
31
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
onCleanup(() => router.dispose())
|
|
33
|
+
|
|
34
|
+
const onUpdate = (props: FileRouterProps) => {
|
|
35
|
+
const newConfigStr = JSON.stringify(props.config)
|
|
36
|
+
if (newConfigStr !== configStr) {
|
|
37
|
+
config = props.config
|
|
38
|
+
configStr = newConfigStr
|
|
39
|
+
router.init(config)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return (nextProps) => (
|
|
44
|
+
onUpdate(nextProps),
|
|
45
|
+
createElement(
|
|
46
|
+
RouterContext,
|
|
47
|
+
{ value: router.contextValue },
|
|
48
|
+
router.getChildren()
|
|
49
|
+
)
|
|
40
50
|
)
|
|
41
51
|
}
|