kiru 0.54.4 → 1.1.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 → appHandle.d.ts} +4 -4
- package/dist/appHandle.d.ts.map +1 -0
- package/dist/{appContext.js → appHandle.js} +13 -10
- 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 +7 -6
- 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 -30
- 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 +19 -0
- package/dist/devtools.js.map +1 -0
- package/dist/dom/commit.d.ts +5 -0
- package/dist/dom/commit.d.ts.map +1 -0
- package/dist/dom/commit.js +94 -0
- package/dist/dom/commit.js.map +1 -0
- package/dist/dom/focus.d.ts +4 -0
- package/dist/dom/focus.d.ts.map +1 -0
- package/dist/dom/focus.js +32 -0
- package/dist/dom/focus.js.map +1 -0
- package/dist/dom/index.d.ts +4 -0
- package/dist/dom/index.d.ts.map +1 -0
- package/dist/dom/index.js +4 -0
- package/dist/dom/index.js.map +1 -0
- package/dist/dom/nodes.d.ts +12 -0
- package/dist/dom/nodes.d.ts.map +1 -0
- package/dist/dom/nodes.js +165 -0
- package/dist/dom/nodes.js.map +1 -0
- package/dist/dom/props.d.ts +8 -0
- package/dist/dom/props.d.ts.map +1 -0
- package/dist/dom/props.js +675 -0
- package/dist/dom/props.js.map +1 -0
- package/dist/env.d.ts +2 -0
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +2 -0
- package/dist/env.js.map +1 -1
- package/dist/globalContext.d.ts +17 -23
- package/dist/globalContext.d.ts.map +1 -1
- package/dist/globalContext.js +31 -53
- package/dist/globalContext.js.map +1 -1
- package/dist/globals.d.ts +21 -4
- package/dist/globals.d.ts.map +1 -1
- package/dist/globals.js +22 -5
- 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 +21 -8
- package/dist/hmr.d.ts.map +1 -1
- package/dist/hmr.js +58 -37
- package/dist/hmr.js.map +1 -1
- package/dist/hooks/index.d.ts +4 -14
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +4 -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 +19 -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 +18 -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 +19 -0
- package/dist/hooks/onMount.js.map +1 -0
- package/dist/hooks/setup.d.ts +13 -0
- package/dist/hooks/setup.d.ts.map +1 -0
- package/dist/hooks/setup.js +54 -0
- package/dist/hooks/setup.js.map +1 -0
- package/dist/hooks/utils.d.ts +2 -63
- package/dist/hooks/utils.d.ts.map +1 -1
- package/dist/hooks/utils.js +17 -144
- package/dist/hooks/utils.js.map +1 -1
- package/dist/index.d.ts +9 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -8
- 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 +15 -28
- 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/head.js +2 -2
- package/dist/router/head.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/pageConfig.js +2 -2
- package/dist/router/pageConfig.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 +91 -73
- 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 +14 -37
- 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 +24 -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 +40 -50
- package/dist/types.d.ts.map +1 -1
- package/dist/types.dom.d.ts +5 -8
- 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/format.d.ts.map +1 -1
- package/dist/utils/format.js +4 -1
- package/dist/utils/format.js.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 +72 -0
- package/dist/viewTransitions.js.map +1 -0
- package/package.json +1 -1
- package/src/{appContext.ts → appHandle.ts} +22 -17
- package/src/components/derive.ts +74 -69
- package/src/components/index.ts +0 -1
- package/src/components/lazy.ts +10 -10
- package/src/components/portal.ts +2 -3
- package/src/components/transition.ts +33 -39
- package/src/constants.ts +0 -8
- package/src/context.ts +30 -23
- package/src/devtools.ts +18 -0
- package/src/dom/commit.ts +133 -0
- package/src/dom/focus.ts +34 -0
- package/src/dom/index.ts +3 -0
- package/src/dom/nodes.ts +204 -0
- package/src/dom/props.ts +818 -0
- package/src/env.ts +3 -0
- package/src/globalContext.ts +51 -85
- package/src/globals.ts +25 -6
- package/src/{recursiveRender.ts → headlessRender.ts} +18 -18
- package/src/hmr.ts +60 -42
- package/src/hooks/index.ts +4 -14
- package/src/hooks/onBeforeMount.ts +18 -0
- package/src/hooks/onCleanup.ts +21 -0
- package/src/hooks/onMount.ts +18 -0
- package/src/hooks/setup.ts +70 -0
- package/src/hooks/utils.ts +24 -239
- package/src/index.ts +17 -7
- package/src/profiling.ts +22 -20
- package/src/reconciler.ts +21 -33
- 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/head.ts +2 -2
- package/src/router/link.ts +11 -25
- package/src/router/pageConfig.ts +2 -2
- package/src/router/server/index.ts +24 -13
- package/src/router/types.ts +15 -8
- package/src/scheduler.ts +116 -98
- package/src/signals/base.ts +13 -42
- package/src/signals/computed.ts +1 -62
- package/src/signals/effect.ts +93 -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 +70 -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 +6 -10
- package/src/types.ts +51 -60
- package/src/types.utils.ts +3 -4
- package/src/utils/format.ts +3 -1
- package/src/utils/vdom.ts +44 -15
- package/src/viewTransitions.ts +89 -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/dom.d.ts +0 -10
- package/dist/dom.d.ts.map +0 -1
- package/dist/dom.js +0 -634
- package/dist/dom.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/dom.ts +0 -809
- 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 -40
- 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
package/src/env.ts
CHANGED
package/src/globalContext.ts
CHANGED
|
@@ -1,63 +1,16 @@
|
|
|
1
1
|
import { __DEV__ } from "./env.js"
|
|
2
|
-
import {
|
|
2
|
+
import { createHmrContext } from "./hmr.js"
|
|
3
3
|
import { createProfilingContext } from "./profiling.js"
|
|
4
4
|
import { fileRouterInstance } from "./router/globals.js"
|
|
5
5
|
import type { FileRouterController } from "./router/fileRouterController"
|
|
6
|
-
import type {
|
|
7
|
-
import type { Store } from "./store"
|
|
8
|
-
import type { SWRCache } from "./swr"
|
|
9
|
-
import type { requestUpdate } from "./index.js"
|
|
6
|
+
import type { AppHandle } from "./appHandle"
|
|
10
7
|
|
|
11
8
|
export { createKiruGlobalContext, type GlobalKiruEvent, type KiruGlobalContext }
|
|
12
9
|
|
|
13
|
-
interface ReactiveMap<V> {
|
|
14
|
-
add(key: string, value: V): void
|
|
15
|
-
delete(key: string): void
|
|
16
|
-
subscribe(cb: (value: Record<string, V>) => void): () => void
|
|
17
|
-
readonly size: number
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function createReactiveMap<V>(): ReactiveMap<V> {
|
|
21
|
-
const map = new Map<string, V>()
|
|
22
|
-
const listeners = new Set<(value: Record<string, V>) => void>()
|
|
23
|
-
|
|
24
|
-
function add(key: string, value: V): void {
|
|
25
|
-
if (map.has(key)) return
|
|
26
|
-
map.set(key, value)
|
|
27
|
-
notify()
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function deleteKey(key: string): void {
|
|
31
|
-
if (!map.has(key)) return
|
|
32
|
-
map.delete(key)
|
|
33
|
-
notify()
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function notify(): void {
|
|
37
|
-
const val = Object.fromEntries(map)
|
|
38
|
-
listeners.forEach((cb) => cb(val))
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function subscribe(cb: (value: Record<string, V>) => void): () => void {
|
|
42
|
-
listeners.add(cb)
|
|
43
|
-
cb(Object.fromEntries(map))
|
|
44
|
-
return () => listeners.delete(cb)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return {
|
|
48
|
-
add,
|
|
49
|
-
delete: deleteKey,
|
|
50
|
-
subscribe,
|
|
51
|
-
get size() {
|
|
52
|
-
return map.size
|
|
53
|
-
},
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
10
|
type Evt =
|
|
58
11
|
| {
|
|
59
12
|
name: "mount"
|
|
60
|
-
data?:
|
|
13
|
+
data?: undefined
|
|
61
14
|
}
|
|
62
15
|
| {
|
|
63
16
|
name: "unmount"
|
|
@@ -74,52 +27,51 @@ type Evt =
|
|
|
74
27
|
|
|
75
28
|
type GlobalKiruEvent = Evt["name"]
|
|
76
29
|
|
|
77
|
-
|
|
78
|
-
|
|
30
|
+
export type DebuggerEntry = {
|
|
31
|
+
label: string
|
|
32
|
+
signal: Kiru.Signal<unknown>
|
|
79
33
|
}
|
|
80
34
|
|
|
81
35
|
interface KiruGlobalContext {
|
|
82
|
-
readonly apps:
|
|
83
|
-
emit<T extends Evt>(event: T["name"],
|
|
36
|
+
readonly apps: AppHandle[]
|
|
37
|
+
emit<T extends Evt>(event: T["name"], app: AppHandle, data?: T["data"]): void
|
|
84
38
|
on<T extends Evt>(
|
|
85
39
|
event: T["name"],
|
|
86
|
-
callback: (
|
|
40
|
+
callback: (app: AppHandle, data: T["data"]) => void
|
|
87
41
|
): void
|
|
88
42
|
off<T extends Evt>(
|
|
89
43
|
event: T["name"],
|
|
90
|
-
callback: (
|
|
44
|
+
callback: (app: AppHandle, data?: T["data"]) => void
|
|
91
45
|
): void
|
|
92
|
-
|
|
93
|
-
|
|
46
|
+
devtools?: {
|
|
47
|
+
track: (signal: Kiru.Signal<unknown>, label?: string) => void
|
|
48
|
+
untrack: (signal: Kiru.Signal<unknown>) => void
|
|
49
|
+
subscribe: (callback: (entries: Set<DebuggerEntry>) => void) => () => void
|
|
50
|
+
}
|
|
51
|
+
HMRContext?: ReturnType<typeof createHmrContext>
|
|
94
52
|
profilingContext?: ReturnType<typeof createProfilingContext>
|
|
95
|
-
SWRGlobalCache?: SWRCache
|
|
96
53
|
fileRouterInstance?: {
|
|
97
54
|
current: FileRouterController | null
|
|
98
55
|
}
|
|
99
|
-
getSchedulerInterface?: (app: AppContext) => SchedulerInterface | null
|
|
100
56
|
}
|
|
101
57
|
|
|
102
58
|
function createKiruGlobalContext(): KiruGlobalContext {
|
|
103
|
-
const
|
|
104
|
-
const contextToSchedulerInterface = new WeakMap<
|
|
105
|
-
AppContext,
|
|
106
|
-
SchedulerInterface
|
|
107
|
-
>()
|
|
59
|
+
const apps = new Set<AppHandle>()
|
|
108
60
|
const listeners = new Map<
|
|
109
61
|
GlobalKiruEvent,
|
|
110
|
-
Set<(
|
|
62
|
+
Set<(app: AppHandle, data?: Evt["data"]) => void>
|
|
111
63
|
>()
|
|
112
64
|
function emit<T extends Evt>(
|
|
113
65
|
event: T["name"],
|
|
114
|
-
|
|
66
|
+
app: AppHandle,
|
|
115
67
|
data?: T["data"]
|
|
116
68
|
): void {
|
|
117
|
-
listeners.get(event)?.forEach((cb) => cb(
|
|
69
|
+
listeners.get(event)?.forEach((cb) => cb(app, data))
|
|
118
70
|
}
|
|
119
71
|
|
|
120
72
|
function on<T extends Evt>(
|
|
121
73
|
event: T["name"],
|
|
122
|
-
callback: (
|
|
74
|
+
callback: (app: AppHandle, data: T["data"]) => void
|
|
123
75
|
): void {
|
|
124
76
|
if (!listeners.has(event)) {
|
|
125
77
|
listeners.set(event, new Set())
|
|
@@ -129,14 +81,14 @@ function createKiruGlobalContext(): KiruGlobalContext {
|
|
|
129
81
|
|
|
130
82
|
function off<T extends Evt>(
|
|
131
83
|
event: T["name"],
|
|
132
|
-
callback: (ctx:
|
|
84
|
+
callback: (ctx: AppHandle, data?: T["data"]) => void
|
|
133
85
|
): void {
|
|
134
86
|
listeners.get(event)?.delete(callback)
|
|
135
87
|
}
|
|
136
88
|
|
|
137
89
|
const globalContext: KiruGlobalContext = {
|
|
138
90
|
get apps() {
|
|
139
|
-
return Array.from(
|
|
91
|
+
return Array.from(apps)
|
|
140
92
|
},
|
|
141
93
|
emit,
|
|
142
94
|
on,
|
|
@@ -144,24 +96,38 @@ function createKiruGlobalContext(): KiruGlobalContext {
|
|
|
144
96
|
}
|
|
145
97
|
|
|
146
98
|
// Initialize event listeners
|
|
147
|
-
on("mount", (
|
|
148
|
-
|
|
149
|
-
if (requestUpdate && typeof requestUpdate === "function") {
|
|
150
|
-
contextToSchedulerInterface.set(ctx, { requestUpdate })
|
|
151
|
-
}
|
|
152
|
-
})
|
|
153
|
-
on("unmount", (ctx) => {
|
|
154
|
-
contexts.delete(ctx)
|
|
155
|
-
contextToSchedulerInterface.delete(ctx)
|
|
156
|
-
})
|
|
99
|
+
on("mount", (app) => apps.add(app))
|
|
100
|
+
on("unmount", (app) => apps.delete(app))
|
|
157
101
|
|
|
158
102
|
if (__DEV__) {
|
|
159
|
-
globalContext.HMRContext =
|
|
103
|
+
globalContext.HMRContext = createHmrContext()
|
|
160
104
|
globalContext.profilingContext = createProfilingContext()
|
|
161
|
-
globalContext.stores = createReactiveMap()
|
|
162
105
|
globalContext.fileRouterInstance = fileRouterInstance
|
|
163
|
-
|
|
164
|
-
|
|
106
|
+
|
|
107
|
+
const debuggerEntries = new Set<DebuggerEntry>()
|
|
108
|
+
const subscribers = new Set<(debuggerEntries: Set<DebuggerEntry>) => void>()
|
|
109
|
+
|
|
110
|
+
globalContext.devtools = {
|
|
111
|
+
track: (signal, label) => {
|
|
112
|
+
debuggerEntries.add({
|
|
113
|
+
label: label ?? signal.displayName ?? "Unnamed Signal",
|
|
114
|
+
signal,
|
|
115
|
+
})
|
|
116
|
+
subscribers.forEach((cb) => cb(debuggerEntries))
|
|
117
|
+
},
|
|
118
|
+
untrack: (signal) => {
|
|
119
|
+
debuggerEntries.forEach((entry) => {
|
|
120
|
+
if (entry.signal === signal) {
|
|
121
|
+
debuggerEntries.delete(entry)
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
subscribers.forEach((cb) => cb(debuggerEntries))
|
|
125
|
+
},
|
|
126
|
+
subscribe: (cb) => {
|
|
127
|
+
subscribers.add(cb)
|
|
128
|
+
cb(debuggerEntries)
|
|
129
|
+
return () => subscribers.delete(cb)
|
|
130
|
+
},
|
|
165
131
|
}
|
|
166
132
|
}
|
|
167
133
|
|
package/src/globals.ts
CHANGED
|
@@ -1,17 +1,36 @@
|
|
|
1
|
-
|
|
1
|
+
import { Setup } from "./hooks/index.js"
|
|
2
|
+
import { isBrowser } from "./env.js"
|
|
3
|
+
export { node, renderMode, hydrationMode, setups, postEffectCleanups }
|
|
2
4
|
|
|
5
|
+
/**
|
|
6
|
+
* A reference to the current VNode (always a component) being rendered.
|
|
7
|
+
*/
|
|
3
8
|
const node = {
|
|
4
9
|
current: null as Kiru.VNode | null,
|
|
5
10
|
}
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
/**
|
|
13
|
+
* The current render mode. Can be "dom" "string", "stream", or "hydrate".
|
|
14
|
+
*/
|
|
11
15
|
const renderMode = {
|
|
12
|
-
current: (
|
|
16
|
+
current: (isBrowser ? "dom" : "string") as Kiru.RenderMode,
|
|
13
17
|
}
|
|
14
18
|
|
|
19
|
+
/**
|
|
20
|
+
* The current hydration mode. Can be "static" or "dynamic".
|
|
21
|
+
* Used to indicate whether the page being hydrated will contain streamed content.
|
|
22
|
+
*/
|
|
15
23
|
const hydrationMode = {
|
|
16
24
|
current: "dynamic" as "static" | "dynamic",
|
|
17
25
|
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* A map of VNodes (components) to their setup functions.
|
|
29
|
+
*/
|
|
30
|
+
const setups: WeakMap<Kiru.VNode, Setup<any>> = new WeakMap()
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Cleanup functions from onMount() that run after components
|
|
34
|
+
* have been unmounted and the browser has painted.
|
|
35
|
+
*/
|
|
36
|
+
const postEffectCleanups: (() => void)[] = []
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { node
|
|
1
|
+
import { node } from "./globals.js"
|
|
2
2
|
import {
|
|
3
3
|
isVNode,
|
|
4
4
|
encodeHtmlEntities,
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
isPrimitiveChild,
|
|
9
9
|
isValidTextChild,
|
|
10
10
|
} from "./utils/index.js"
|
|
11
|
-
import { isStreamDataThrowValue } from "./
|
|
11
|
+
import { isStreamDataThrowValue } from "./statefulPromise.js"
|
|
12
12
|
import { Signal } from "./signals/base.js"
|
|
13
13
|
import { $ERROR_BOUNDARY, voidElements, $STREAM_DATA } from "./constants.js"
|
|
14
14
|
import { __DEV__ } from "./env.js"
|
|
@@ -16,12 +16,10 @@ import type { ErrorBoundaryNode } from "./types.utils"
|
|
|
16
16
|
|
|
17
17
|
export interface HeadlessRenderContext {
|
|
18
18
|
write(chunk: string): void
|
|
19
|
-
onStreamData?: (data: Kiru.
|
|
19
|
+
onStreamData?: (data: Kiru.StatefulPromiseBase<unknown>[]) => void
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
function render(
|
|
22
|
+
export function headlessRender(
|
|
25
23
|
ctx: HeadlessRenderContext,
|
|
26
24
|
el: unknown,
|
|
27
25
|
parent: Kiru.VNode | null,
|
|
@@ -37,7 +35,7 @@ function render(
|
|
|
37
35
|
return ctx.write(el.toString())
|
|
38
36
|
}
|
|
39
37
|
if (el instanceof Array) {
|
|
40
|
-
return el.forEach((c, i) =>
|
|
38
|
+
return el.forEach((c, i) => headlessRender(ctx, c, parent, i))
|
|
41
39
|
}
|
|
42
40
|
if (Signal.isSignal(el)) {
|
|
43
41
|
const value = el.peek()
|
|
@@ -68,7 +66,7 @@ function render(
|
|
|
68
66
|
if (isExoticType(type)) {
|
|
69
67
|
if (type === $ERROR_BOUNDARY) {
|
|
70
68
|
let boundaryBuffer = ""
|
|
71
|
-
const streamPromises = new Set<Kiru.
|
|
69
|
+
const streamPromises = new Set<Kiru.StatefulPromiseBase<unknown>>()
|
|
72
70
|
const boundaryCtx: HeadlessRenderContext = {
|
|
73
71
|
write(chunk) {
|
|
74
72
|
boundaryBuffer += chunk
|
|
@@ -78,7 +76,7 @@ function render(
|
|
|
78
76
|
},
|
|
79
77
|
}
|
|
80
78
|
try {
|
|
81
|
-
|
|
79
|
+
headlessRender(boundaryCtx, children, el, idx)
|
|
82
80
|
// flush successful render
|
|
83
81
|
ctx.write(boundaryBuffer)
|
|
84
82
|
ctx.onStreamData?.([...streamPromises])
|
|
@@ -91,27 +89,29 @@ function render(
|
|
|
91
89
|
onError?.(e)
|
|
92
90
|
const fallbackContent =
|
|
93
91
|
typeof fallback === "function" ? fallback(e) : fallback
|
|
94
|
-
|
|
92
|
+
headlessRender(ctx, fallbackContent, el, 0)
|
|
95
93
|
}
|
|
96
94
|
return
|
|
97
95
|
}
|
|
98
96
|
|
|
99
|
-
|
|
97
|
+
headlessRender(ctx, children, el, idx)
|
|
100
98
|
return
|
|
101
99
|
}
|
|
102
100
|
|
|
103
|
-
if (typeof type
|
|
101
|
+
if (typeof type === "function") {
|
|
104
102
|
try {
|
|
105
|
-
hookIndex.current = 0
|
|
106
103
|
node.current = el
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
let children = type(props)
|
|
105
|
+
if (typeof children === "function") {
|
|
106
|
+
children = children(props)
|
|
107
|
+
}
|
|
108
|
+
headlessRender(ctx, children, el, idx)
|
|
109
109
|
return
|
|
110
110
|
} catch (error) {
|
|
111
111
|
if (isStreamDataThrowValue(error)) {
|
|
112
112
|
const { fallback, data } = error[$STREAM_DATA]
|
|
113
113
|
ctx.onStreamData?.(data)
|
|
114
|
-
return
|
|
114
|
+
return headlessRender(ctx, fallback, el, 0)
|
|
115
115
|
}
|
|
116
116
|
throw error
|
|
117
117
|
} finally {
|
|
@@ -134,9 +134,9 @@ function render(
|
|
|
134
134
|
)
|
|
135
135
|
)
|
|
136
136
|
} else if (Array.isArray(children)) {
|
|
137
|
-
children.forEach((c, i) =>
|
|
137
|
+
children.forEach((c, i) => headlessRender(ctx, c, el, i))
|
|
138
138
|
} else {
|
|
139
|
-
|
|
139
|
+
headlessRender(ctx, children, el, 0)
|
|
140
140
|
}
|
|
141
141
|
ctx.write(`</${type}>`)
|
|
142
142
|
}
|
package/src/hmr.ts
CHANGED
|
@@ -2,9 +2,7 @@ import { $HMR_ACCEPT, $DEV_FILE_LINK } from "./constants.js"
|
|
|
2
2
|
import { traverseApply } from "./utils/index.js"
|
|
3
3
|
import { flushSync, requestUpdate } from "./scheduler.js"
|
|
4
4
|
import { Signal } from "./signals/base.js"
|
|
5
|
-
import type {
|
|
6
|
-
import type { Store } from "./store.js"
|
|
7
|
-
import type { AppContext } from "./appContext.js"
|
|
5
|
+
import type { Effect } from "./signals/effect.js"
|
|
8
6
|
|
|
9
7
|
export type HMRAccept<T = {}> = {
|
|
10
8
|
provide: () => T
|
|
@@ -15,7 +13,7 @@ export type HMRAccept<T = {}> = {
|
|
|
15
13
|
export type GenericHMRAcceptor<T = {}> = {
|
|
16
14
|
[$HMR_ACCEPT]: HMRAccept<T>
|
|
17
15
|
}
|
|
18
|
-
type HotVar = Kiru.FC |
|
|
16
|
+
type HotVar = Kiru.FC | Signal<any> | Kiru.Context<any>
|
|
19
17
|
|
|
20
18
|
type HotVarDesc = {
|
|
21
19
|
type: string
|
|
@@ -43,7 +41,8 @@ export function isGenericHmrAcceptor(
|
|
|
43
41
|
|
|
44
42
|
type ModuleMemory = {
|
|
45
43
|
hotVars: Map<string, HotVarDesc>
|
|
46
|
-
|
|
44
|
+
unnamedEffects: Array<Effect>
|
|
45
|
+
hmrCallbacks: Array<() => void>
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
type HotVarRegistrationEntry = {
|
|
@@ -52,18 +51,22 @@ type HotVarRegistrationEntry = {
|
|
|
52
51
|
link: string
|
|
53
52
|
}
|
|
54
53
|
|
|
55
|
-
export function
|
|
54
|
+
export function createHmrContext() {
|
|
56
55
|
type FilePath = string
|
|
57
56
|
const moduleMap = new Map<FilePath, ModuleMemory>()
|
|
58
57
|
let currentModuleFilePath: string | null = null
|
|
59
58
|
let currentModuleMemory: ModuleMemory | null = null
|
|
60
59
|
let isModuleReplacementExecution = false
|
|
61
60
|
const isReplacement = () => isModuleReplacementExecution
|
|
62
|
-
let
|
|
61
|
+
let isWaitingForNextEffect = false
|
|
63
62
|
|
|
64
|
-
const
|
|
63
|
+
const globalHmrCallbacks: Array<() => void> = []
|
|
65
64
|
const onHmr = (callback: () => void) => {
|
|
66
|
-
|
|
65
|
+
if (currentModuleMemory) {
|
|
66
|
+
currentModuleMemory.hmrCallbacks.push(callback)
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
globalHmrCallbacks.push(callback)
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
const prepare = (filePath: string) => {
|
|
@@ -72,14 +75,17 @@ export function createHMRContext() {
|
|
|
72
75
|
if (!mod) {
|
|
73
76
|
mod = {
|
|
74
77
|
hotVars: new Map(),
|
|
75
|
-
|
|
78
|
+
unnamedEffects: [],
|
|
79
|
+
hmrCallbacks: [],
|
|
76
80
|
}
|
|
77
81
|
moduleMap.set(filePath, mod)
|
|
78
82
|
} else {
|
|
79
|
-
while (
|
|
80
|
-
|
|
81
|
-
|
|
83
|
+
while (mod.hmrCallbacks.length) mod.hmrCallbacks.shift()!()
|
|
84
|
+
while (globalHmrCallbacks.length) globalHmrCallbacks.shift()!()
|
|
85
|
+
for (const effect of mod.unnamedEffects) {
|
|
86
|
+
effect.stop()
|
|
82
87
|
}
|
|
88
|
+
mod.unnamedEffects.length = 0
|
|
83
89
|
}
|
|
84
90
|
|
|
85
91
|
currentModuleMemory = mod!
|
|
@@ -92,26 +98,20 @@ export function createHMRContext() {
|
|
|
92
98
|
if (currentModuleMemory === null)
|
|
93
99
|
throw new Error("[kiru]: HMR could not register: No active module")
|
|
94
100
|
|
|
95
|
-
let
|
|
101
|
+
let dirtyNodes = new Set<Kiru.VNode>()
|
|
96
102
|
for (const [name, newEntry] of Object.entries(hotVarRegistrationEntries)) {
|
|
97
103
|
const oldEntry = currentModuleMemory.hotVars.get(name)
|
|
98
104
|
|
|
99
105
|
// @ts-ignore - this is how we tell devtools what file the hotvar is from
|
|
100
106
|
newEntry.value[$DEV_FILE_LINK] = newEntry.link
|
|
101
107
|
|
|
102
|
-
if (
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
oldEntry.value.__next = newEntry.value
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (newEntry.type === "createStore") {
|
|
114
|
-
window.__kiru.stores!.add(name, newEntry.value as Store<any, any>)
|
|
108
|
+
if (oldEntry?.value) {
|
|
109
|
+
/**
|
|
110
|
+
* this is how, when the previous value has been stored somewhere else (eg. in a Map, or by Vike),
|
|
111
|
+
* we can trace it to its current version by using latest(value)
|
|
112
|
+
*/
|
|
113
|
+
// @ts-ignore
|
|
114
|
+
oldEntry.value.__next = newEntry.value
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
currentModuleMemory.hotVars.set(name, newEntry)
|
|
@@ -127,20 +127,20 @@ export function createHMRContext() {
|
|
|
127
127
|
continue
|
|
128
128
|
}
|
|
129
129
|
if (oldEntry.type === "component" && newEntry.type === "component") {
|
|
130
|
-
window.__kiru.apps.forEach((
|
|
131
|
-
traverseApply(
|
|
130
|
+
window.__kiru.apps.forEach((app) => {
|
|
131
|
+
traverseApply(app.rootNode, (vNode) => {
|
|
132
132
|
if (vNode.type === oldEntry.value) {
|
|
133
133
|
vNode.type = newEntry.value as any
|
|
134
|
-
|
|
134
|
+
dirtyNodes.add(vNode)
|
|
135
135
|
}
|
|
136
136
|
})
|
|
137
137
|
})
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
if (
|
|
141
|
+
if (dirtyNodes.size) {
|
|
142
142
|
_isHmrUpdate = true
|
|
143
|
-
|
|
143
|
+
dirtyNodes.forEach((n) => requestUpdate(n))
|
|
144
144
|
flushSync()
|
|
145
145
|
_isHmrUpdate = false
|
|
146
146
|
}
|
|
@@ -150,16 +150,14 @@ export function createHMRContext() {
|
|
|
150
150
|
currentModuleFilePath = null
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
},
|
|
157
|
-
isWaitingForNextWatchCall() {
|
|
158
|
-
return isWaitingForNextWatchCall
|
|
153
|
+
const moduleEffects = {
|
|
154
|
+
registerNext() {
|
|
155
|
+
isWaitingForNextEffect = true
|
|
159
156
|
},
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
157
|
+
push(effect: Effect<any>) {
|
|
158
|
+
if (!isWaitingForNextEffect) return
|
|
159
|
+
currentModuleMemory!.unnamedEffects.push(effect)
|
|
160
|
+
isWaitingForNextEffect = false
|
|
163
161
|
},
|
|
164
162
|
}
|
|
165
163
|
|
|
@@ -167,10 +165,30 @@ export function createHMRContext() {
|
|
|
167
165
|
register,
|
|
168
166
|
prepare,
|
|
169
167
|
isReplacement,
|
|
170
|
-
|
|
168
|
+
moduleEffects,
|
|
171
169
|
onHmr,
|
|
172
170
|
getCurrentFilePath() {
|
|
173
171
|
return currentModuleFilePath
|
|
174
172
|
},
|
|
175
173
|
}
|
|
176
174
|
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Queues a callback to be fired when HMR is triggered. This is a no-op in non-browser environments or in production.
|
|
178
|
+
* - If called during current module evaluation, the callback will be fired the next time the current module is evaluated.
|
|
179
|
+
* - If called at any other time, the callback will be fired the next time HMR is triggered.
|
|
180
|
+
* @see https://kirujs.dev/docs/api/lifecycles#onHmr
|
|
181
|
+
*
|
|
182
|
+
* ```ts
|
|
183
|
+
* import { onHmr } from "kiru"
|
|
184
|
+
* // start an interval in the module scope
|
|
185
|
+
* const interval = setInterval(() => {...}, 1000)
|
|
186
|
+
* // stop the interval when this file is reloaded
|
|
187
|
+
* onHmr(() => clearInterval(interval))
|
|
188
|
+
```
|
|
189
|
+
*/
|
|
190
|
+
export function onHmr(callback: () => void): void {
|
|
191
|
+
if ("window" in globalThis && window.__kiru.HMRContext) {
|
|
192
|
+
window.__kiru.HMRContext.onHmr(callback)
|
|
193
|
+
}
|
|
194
|
+
}
|
package/src/hooks/index.ts
CHANGED
|
@@ -1,15 +1,5 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export * from "./
|
|
3
|
-
export * from "./
|
|
4
|
-
export * from "./
|
|
5
|
-
export * from "./useEffectEvent.js"
|
|
6
|
-
export * from "./useId.js"
|
|
7
|
-
export * from "./useLayoutEffect.js"
|
|
8
|
-
export * from "./useMemo.js"
|
|
9
|
-
export * from "./usePromise.js"
|
|
10
|
-
export * from "./useReducer.js"
|
|
11
|
-
export * from "./useRef.js"
|
|
12
|
-
export * from "./useState.js"
|
|
13
|
-
export * from "./useSyncExternalStore.js"
|
|
14
|
-
export * from "./useViewTransition.js"
|
|
1
|
+
export * from "./onCleanup.js"
|
|
2
|
+
export * from "./onMount.js"
|
|
3
|
+
export * from "./onBeforeMount.js"
|
|
4
|
+
export * from "./setup.js"
|
|
15
5
|
export * from "./utils.js"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { sideEffectsEnabled } from "../utils/index.js"
|
|
2
|
+
import { getVNodeLifecycleHooks, wrapLifecycleHookCallback } from "./utils.js"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Registers a callback that runs after the component is first mounted to the DOM, but before the DOM is painted.
|
|
6
|
+
* Optionally returns a cleanup function that will run when the component unmounts.
|
|
7
|
+
* Intended for use during component setup when the component returns a render function.
|
|
8
|
+
*
|
|
9
|
+
* @see https://kirujs.dev/docs/api/lifecycles#onBeforeMount
|
|
10
|
+
*/
|
|
11
|
+
export function onBeforeMount(fn: () => (() => void) | void): void {
|
|
12
|
+
if (!sideEffectsEnabled()) return
|
|
13
|
+
const hooks = getVNodeLifecycleHooks()
|
|
14
|
+
if (!hooks) {
|
|
15
|
+
throw new Error("Cannot queue beforeMount effect outside of a component")
|
|
16
|
+
}
|
|
17
|
+
hooks.pre.push(wrapLifecycleHookCallback(fn, hooks.preCleanups))
|
|
18
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { node } from "../globals.js"
|
|
2
|
+
import {
|
|
3
|
+
generateRandomID,
|
|
4
|
+
registerVNodeCleanup,
|
|
5
|
+
sideEffectsEnabled,
|
|
6
|
+
} from "../utils/index.js"
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Registers a cleanup function that runs when the component unmounts.
|
|
10
|
+
* Intended for use during component setup when the component returns a render function.
|
|
11
|
+
*
|
|
12
|
+
* @see https://kirujs.dev/docs/api/lifecycles#onCleanup
|
|
13
|
+
*/
|
|
14
|
+
export function onCleanup(fn: () => void): void {
|
|
15
|
+
if (!sideEffectsEnabled()) return
|
|
16
|
+
const vNode = node.current!
|
|
17
|
+
if (!vNode) {
|
|
18
|
+
throw new Error("Cannot queue onCleanup effect outside of a component")
|
|
19
|
+
}
|
|
20
|
+
registerVNodeCleanup(vNode, generateRandomID(10), fn)
|
|
21
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { sideEffectsEnabled } from "../utils/index.js"
|
|
2
|
+
import { getVNodeLifecycleHooks, wrapLifecycleHookCallback } from "./utils.js"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Registers a callback that runs after the component is first mounted to the DOM.
|
|
6
|
+
* Optionally returns a cleanup function that will run after the component unmounts.
|
|
7
|
+
* Intended for use during component setup when the component returns a render function.
|
|
8
|
+
*
|
|
9
|
+
* @see https://kirujs.dev/docs/api/lifecycles#onMount
|
|
10
|
+
*/
|
|
11
|
+
export function onMount(fn: () => (() => void) | void): void {
|
|
12
|
+
if (!sideEffectsEnabled()) return
|
|
13
|
+
const hooks = getVNodeLifecycleHooks()
|
|
14
|
+
if (!hooks) {
|
|
15
|
+
throw new Error("Cannot queue onMount effect outside of a component")
|
|
16
|
+
}
|
|
17
|
+
hooks.post.push(wrapLifecycleHookCallback(fn, hooks.postCleanups))
|
|
18
|
+
}
|