kiru 0.48.3 → 0.49.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/action.d.ts +22 -0
- package/dist/action.d.ts.map +1 -0
- package/dist/action.js +20 -0
- package/dist/action.js.map +1 -0
- package/dist/components/index.d.ts +5 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +5 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/lazy.d.ts.map +1 -0
- package/dist/{lazy.js → components/lazy.js} +11 -11
- package/dist/components/lazy.js.map +1 -0
- package/dist/{memo.d.ts → components/memo.d.ts} +1 -1
- package/dist/components/memo.d.ts.map +1 -0
- package/dist/{memo.js → components/memo.js} +2 -2
- package/dist/components/memo.js.map +1 -0
- package/dist/components/portal.d.ts.map +1 -0
- package/dist/{portal.js → components/portal.js} +6 -6
- package/dist/components/portal.js.map +1 -0
- package/dist/components/router/index.d.ts.map +1 -0
- package/dist/components/router/index.js.map +1 -0
- package/dist/components/router/route.d.ts.map +1 -0
- package/dist/{router → components/router}/route.js +1 -1
- package/dist/components/router/route.js.map +1 -0
- package/dist/{router → components/router}/router.d.ts +1 -1
- package/dist/components/router/router.d.ts.map +1 -0
- package/dist/{router → components/router}/router.js +8 -8
- package/dist/components/router/router.js.map +1 -0
- package/dist/components/router/routerUtils.d.ts.map +1 -0
- package/dist/components/router/routerUtils.js.map +1 -0
- package/dist/components/transition.d.ts.map +1 -0
- package/dist/{transition.js → components/transition.js} +5 -5
- package/dist/components/transition.js.map +1 -0
- package/dist/constants.d.ts +2 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +79 -1
- package/dist/constants.js.map +1 -1
- package/dist/context.js +1 -1
- package/dist/context.js.map +1 -1
- package/dist/dom.d.ts.map +1 -1
- package/dist/dom.js +8 -9
- package/dist/dom.js.map +1 -1
- package/dist/element.js +2 -2
- package/dist/element.js.map +1 -1
- package/dist/error.js +1 -1
- package/dist/error.js.map +1 -1
- package/dist/form/index.d.ts.map +1 -1
- package/dist/form/index.js +1 -2
- package/dist/form/index.js.map +1 -1
- package/dist/hmr.js +1 -1
- package/dist/hmr.js.map +1 -1
- package/dist/hooks/useAsync.d.ts.map +1 -1
- package/dist/hooks/useAsync.js +2 -2
- package/dist/hooks/useAsync.js.map +1 -1
- package/dist/hooks/useCallback.d.ts.map +1 -1
- package/dist/hooks/useCallback.js +2 -1
- package/dist/hooks/useCallback.js.map +1 -1
- package/dist/hooks/useEffect.d.ts.map +1 -1
- package/dist/hooks/useEffect.js +2 -1
- package/dist/hooks/useEffect.js.map +1 -1
- package/dist/hooks/useEffectEvent.d.ts.map +1 -1
- package/dist/hooks/useEffectEvent.js +2 -1
- package/dist/hooks/useEffectEvent.js.map +1 -1
- package/dist/hooks/useLayoutEffect.d.ts.map +1 -1
- package/dist/hooks/useLayoutEffect.js +2 -1
- package/dist/hooks/useLayoutEffect.js.map +1 -1
- package/dist/hooks/useMemo.d.ts.map +1 -1
- package/dist/hooks/useMemo.js +2 -1
- package/dist/hooks/useMemo.js.map +1 -1
- package/dist/hooks/useReducer.js +2 -2
- package/dist/hooks/useReducer.js.map +1 -1
- package/dist/hooks/useRef.d.ts.map +1 -1
- package/dist/hooks/useRef.js +2 -1
- package/dist/hooks/useRef.js.map +1 -1
- package/dist/hooks/useState.js +2 -2
- package/dist/hooks/useState.js.map +1 -1
- package/dist/hooks/useSyncExternalStore.js +2 -2
- package/dist/hooks/useSyncExternalStore.js.map +1 -1
- package/dist/hooks/useViewTransition.d.ts.map +1 -1
- package/dist/hooks/useViewTransition.js +1 -2
- package/dist/hooks/useViewTransition.js.map +1 -1
- package/dist/hooks/utils.d.ts +0 -1
- package/dist/hooks/utils.d.ts.map +1 -1
- package/dist/hooks/utils.js +1 -2
- package/dist/hooks/utils.js.map +1 -1
- package/dist/index.d.ts +2 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -5
- package/dist/index.js.map +1 -1
- package/dist/reconciler.js +8 -7
- package/dist/reconciler.js.map +1 -1
- package/dist/renderToString.js +1 -2
- package/dist/renderToString.js.map +1 -1
- package/dist/scheduler.js +2 -2
- package/dist/scheduler.js.map +1 -1
- package/dist/signals/base.d.ts.map +1 -1
- package/dist/signals/base.js +1 -2
- package/dist/signals/base.js.map +1 -1
- package/dist/signals/computed.js +1 -1
- package/dist/signals/computed.js.map +1 -1
- package/dist/signals/effect.js +1 -1
- package/dist/signals/effect.js.map +1 -1
- package/dist/signals/watch.d.ts.map +1 -1
- package/dist/signals/watch.js +2 -3
- package/dist/signals/watch.js.map +1 -1
- package/dist/ssr/server.js +1 -2
- package/dist/ssr/server.js.map +1 -1
- package/dist/store.d.ts +1 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +2 -2
- package/dist/store.js.map +1 -1
- package/dist/swr.js +1 -1
- package/dist/swr.js.map +1 -1
- package/dist/types.d.ts +4 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.dom.d.ts +2 -2
- package/dist/types.dom.d.ts.map +1 -1
- package/dist/utils/compare.d.ts +3 -0
- package/dist/utils/compare.d.ts.map +1 -0
- package/dist/utils/compare.js +123 -0
- package/dist/utils/compare.js.map +1 -0
- package/dist/utils/format.d.ts +20 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +129 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/generateId.d.ts.map +1 -0
- package/dist/utils/generateId.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/runtime.d.ts +11 -0
- package/dist/utils/runtime.d.ts.map +1 -0
- package/dist/utils/runtime.js +23 -0
- package/dist/utils/runtime.js.map +1 -0
- package/dist/utils/vdom.d.ts +25 -0
- package/dist/utils/vdom.d.ts.map +1 -0
- package/dist/utils/vdom.js +124 -0
- package/dist/utils/vdom.js.map +1 -0
- package/package.json +6 -6
- package/src/action.ts +42 -0
- package/src/components/index.ts +4 -0
- package/src/{lazy.ts → components/lazy.ts} +12 -12
- package/src/{memo.ts → components/memo.ts} +3 -3
- package/src/{portal.ts → components/portal.ts} +6 -6
- package/src/{router → components/router}/route.ts +1 -1
- package/src/{router → components/router}/router.ts +9 -9
- package/src/{transition.ts → components/transition.ts} +5 -5
- package/src/constants.ts +80 -1
- package/src/context.ts +1 -1
- package/src/customEvents.ts +22 -22
- package/src/dom.ts +7 -8
- package/src/element.ts +2 -2
- package/src/error.ts +1 -1
- package/src/form/index.ts +5 -2
- package/src/hmr.ts +1 -1
- package/src/hooks/useAsync.ts +5 -3
- package/src/hooks/useCallback.ts +2 -1
- package/src/hooks/useEffect.ts +2 -6
- package/src/hooks/useEffectEvent.ts +2 -1
- package/src/hooks/useLayoutEffect.ts +2 -6
- package/src/hooks/useMemo.ts +2 -1
- package/src/hooks/useReducer.ts +2 -2
- package/src/hooks/useRef.ts +2 -1
- package/src/hooks/useState.ts +2 -2
- package/src/hooks/useSyncExternalStore.ts +2 -2
- package/src/hooks/useViewTransition.ts +1 -2
- package/src/hooks/utils.ts +1 -2
- package/src/index.ts +2 -5
- package/src/reconciler.ts +13 -11
- package/src/renderToString.ts +2 -2
- package/src/scheduler.ts +2 -2
- package/src/signals/base.ts +6 -2
- package/src/signals/computed.ts +1 -1
- package/src/signals/effect.ts +1 -1
- package/src/signals/watch.ts +2 -3
- package/src/ssr/server.ts +2 -2
- package/src/store.ts +6 -2
- package/src/swr.ts +3 -3
- package/src/types.dom.ts +2 -1
- package/src/types.ts +9 -2
- package/src/utils/compare.ts +125 -0
- package/src/utils/format.ts +158 -0
- package/src/utils/index.ts +7 -0
- package/src/utils/runtime.ts +25 -0
- package/src/utils/vdom.ts +184 -0
- package/dist/cloneVNode.d.ts +0 -2
- package/dist/cloneVNode.d.ts.map +0 -1
- package/dist/cloneVNode.js +0 -14
- package/dist/cloneVNode.js.map +0 -1
- package/dist/generateId.d.ts.map +0 -1
- package/dist/generateId.js.map +0 -1
- package/dist/lazy.d.ts.map +0 -1
- package/dist/lazy.js.map +0 -1
- package/dist/memo.d.ts.map +0 -1
- package/dist/memo.js.map +0 -1
- package/dist/portal.d.ts.map +0 -1
- package/dist/portal.js.map +0 -1
- package/dist/props.d.ts +0 -4
- package/dist/props.d.ts.map +0 -1
- package/dist/props.js +0 -27
- package/dist/props.js.map +0 -1
- package/dist/router/index.d.ts.map +0 -1
- package/dist/router/index.js.map +0 -1
- package/dist/router/route.d.ts.map +0 -1
- package/dist/router/route.js.map +0 -1
- package/dist/router/router.d.ts.map +0 -1
- package/dist/router/router.js.map +0 -1
- package/dist/router/routerUtils.d.ts.map +0 -1
- package/dist/router/routerUtils.js.map +0 -1
- package/dist/transition.d.ts.map +0 -1
- package/dist/transition.js.map +0 -1
- package/dist/utils.d.ts +0 -52
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -433
- package/dist/utils.js.map +0 -1
- package/dist/warning.d.ts +0 -2
- package/dist/warning.d.ts.map +0 -1
- package/dist/warning.js +0 -4
- package/dist/warning.js.map +0 -1
- package/src/cloneVNode.ts +0 -14
- package/src/props.ts +0 -34
- package/src/utils.ts +0 -518
- package/src/warning.ts +0 -9
- /package/dist/{lazy.d.ts → components/lazy.d.ts} +0 -0
- /package/dist/{portal.d.ts → components/portal.d.ts} +0 -0
- /package/dist/{router → components/router}/index.d.ts +0 -0
- /package/dist/{router → components/router}/index.js +0 -0
- /package/dist/{router → components/router}/route.d.ts +0 -0
- /package/dist/{router → components/router}/routerUtils.d.ts +0 -0
- /package/dist/{router → components/router}/routerUtils.js +0 -0
- /package/dist/{transition.d.ts → components/transition.d.ts} +0 -0
- /package/dist/{generateId.d.ts → utils/generateId.d.ts} +0 -0
- /package/dist/{generateId.js → utils/generateId.js} +0 -0
- /package/src/{router → components/router}/index.ts +0 -0
- /package/src/{router → components/router}/routerUtils.ts +0 -0
- /package/src/{generateId.ts → utils/generateId.ts} +0 -0
package/src/hooks/useState.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __DEV__ } from "../env.js"
|
|
2
|
-
import { noop } from "../utils.js"
|
|
3
|
-
import {
|
|
2
|
+
import { noop, sideEffectsEnabled } from "../utils/index.js"
|
|
3
|
+
import { useHook } from "./utils.js"
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Creates a stateful value, and returns the current value and a function to update it.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { node } from "../globals.js"
|
|
2
2
|
import { KiruError } from "../error.js"
|
|
3
|
-
import { noop } from "../utils.js"
|
|
4
|
-
import {
|
|
3
|
+
import { noop, sideEffectsEnabled } from "../utils/index.js"
|
|
4
|
+
import { useHook } from "./utils.js"
|
|
5
5
|
import { __DEV__ } from "../env.js"
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { flushSync } from "../scheduler.js"
|
|
2
2
|
import { node } from "../globals.js"
|
|
3
|
-
import { noop } from "../utils.js"
|
|
4
|
-
import { sideEffectsEnabled } from "./utils.js"
|
|
3
|
+
import { noop, sideEffectsEnabled } from "../utils/index.js"
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* Allows you to easily use the [View Transition API](https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition)
|
package/src/hooks/utils.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { KiruError } from "../error.js"
|
|
2
2
|
import { __DEV__ } from "../env.js"
|
|
3
3
|
import { hookIndex, node } from "../globals.js"
|
|
4
|
-
import { noop } from "../utils.js"
|
|
4
|
+
import { noop } from "../utils/index.js"
|
|
5
5
|
import { requestUpdate } from "../scheduler.js"
|
|
6
|
-
export { sideEffectsEnabled } from "../utils.js"
|
|
7
6
|
export {
|
|
8
7
|
cleanupHook,
|
|
9
8
|
depsRequireChange,
|
package/src/index.ts
CHANGED
|
@@ -3,19 +3,16 @@ import { createKiruGlobalContext } from "./globalContext.js"
|
|
|
3
3
|
|
|
4
4
|
export type * from "./types"
|
|
5
5
|
export * from "./signals/index.js"
|
|
6
|
+
export * from "./action.js"
|
|
6
7
|
export * from "./appContext.js"
|
|
7
|
-
export * from "./cloneVNode.js"
|
|
8
8
|
export * from "./context.js"
|
|
9
9
|
export * from "./customEvents.js"
|
|
10
10
|
export * from "./element.js"
|
|
11
11
|
export * from "./hooks/index.js"
|
|
12
|
-
export * from "./
|
|
13
|
-
export { memo } from "./memo.js"
|
|
14
|
-
export * from "./portal.js"
|
|
12
|
+
export * from "./components/index.js"
|
|
15
13
|
export * from "./renderToString.js"
|
|
16
14
|
export { nextIdle, flushSync, requestUpdate } from "./scheduler.js"
|
|
17
15
|
export * from "./store.js"
|
|
18
|
-
export * from "./transition.js"
|
|
19
16
|
|
|
20
17
|
if (__DEV__) {
|
|
21
18
|
if ("window" in globalThis) {
|
package/src/reconciler.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { $FRAGMENT, FLAG_PLACEMENT, FLAG_UPDATE } from "./constants.js"
|
|
2
|
-
import { getVNodeAppContext, isVNode, latest } from "./utils.js"
|
|
2
|
+
import { getVNodeAppContext, isVNode, latest } from "./utils/index.js"
|
|
3
3
|
import { Signal } from "./signals/base.js"
|
|
4
4
|
import { __DEV__ } from "./env.js"
|
|
5
5
|
import { createElement, Fragment } from "./element.js"
|
|
@@ -150,11 +150,7 @@ function reconcileChildrenArray(parent: VNode, children: unknown[]) {
|
|
|
150
150
|
function updateSlot(parent: VNode, oldChild: VNode | null, child: unknown) {
|
|
151
151
|
// Update the node if the keys match, otherwise return null.
|
|
152
152
|
const key = oldChild?.props.key
|
|
153
|
-
if (
|
|
154
|
-
(typeof child === "string" && child !== "") ||
|
|
155
|
-
typeof child === "number" ||
|
|
156
|
-
typeof child === "bigint"
|
|
157
|
-
) {
|
|
153
|
+
if (isValidTextNodeValue(child)) {
|
|
158
154
|
if (key !== undefined) return null
|
|
159
155
|
if (
|
|
160
156
|
oldChild?.type === "#text" &&
|
|
@@ -272,11 +268,7 @@ function updateFragment(
|
|
|
272
268
|
}
|
|
273
269
|
|
|
274
270
|
function createChild(parent: VNode, child: unknown): VNode | null {
|
|
275
|
-
if (
|
|
276
|
-
(typeof child === "string" && child !== "") ||
|
|
277
|
-
typeof child === "number" ||
|
|
278
|
-
typeof child === "bigint"
|
|
279
|
-
) {
|
|
271
|
+
if (isValidTextNodeValue(child)) {
|
|
280
272
|
if (__DEV__) {
|
|
281
273
|
dev_emitCreateNode()
|
|
282
274
|
}
|
|
@@ -438,6 +430,16 @@ function updateFromMap(
|
|
|
438
430
|
return null
|
|
439
431
|
}
|
|
440
432
|
|
|
433
|
+
function isValidTextNodeValue(
|
|
434
|
+
value: unknown
|
|
435
|
+
): value is string | number | bigint {
|
|
436
|
+
return (
|
|
437
|
+
(typeof value === "string" && value !== "") ||
|
|
438
|
+
typeof value === "number" ||
|
|
439
|
+
typeof value === "bigint"
|
|
440
|
+
)
|
|
441
|
+
}
|
|
442
|
+
|
|
441
443
|
function propsChanged(oldProps: VNode["props"], newProps: VNode["props"]) {
|
|
442
444
|
const aKeys = Object.keys(oldProps)
|
|
443
445
|
const bKeys = Object.keys(newProps)
|
package/src/renderToString.ts
CHANGED
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
encodeHtmlEntities,
|
|
6
6
|
propsToElementAttributes,
|
|
7
7
|
isExoticType,
|
|
8
|
-
|
|
8
|
+
assertValidElementProps,
|
|
9
|
+
} from "./utils/index.js"
|
|
9
10
|
import { Signal } from "./signals/base.js"
|
|
10
11
|
import { $HYDRATION_BOUNDARY, voidElements } from "./constants.js"
|
|
11
|
-
import { assertValidElementProps } from "./props.js"
|
|
12
12
|
import { HYDRATION_BOUNDARY_MARKER } from "./ssr/hydrationBoundary.js"
|
|
13
13
|
import { __DEV__ } from "./env.js"
|
|
14
14
|
|
package/src/scheduler.ts
CHANGED
|
@@ -23,14 +23,14 @@ import { __DEV__ } from "./env.js"
|
|
|
23
23
|
import { KiruError } from "./error.js"
|
|
24
24
|
import { hookIndex, node, renderMode } from "./globals.js"
|
|
25
25
|
import { hydrationStack } from "./hydration.js"
|
|
26
|
-
import { assertValidElementProps } from "./
|
|
26
|
+
import { assertValidElementProps } from "./utils/index.js"
|
|
27
27
|
import { reconcileChildren } from "./reconciler.js"
|
|
28
28
|
import {
|
|
29
29
|
latest,
|
|
30
30
|
traverseApply,
|
|
31
31
|
isExoticType,
|
|
32
32
|
getVNodeAppContext,
|
|
33
|
-
} from "./utils.js"
|
|
33
|
+
} from "./utils/index.js"
|
|
34
34
|
import type { AppContext } from "./appContext"
|
|
35
35
|
|
|
36
36
|
type VNode = Kiru.VNode
|
package/src/signals/base.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
latest,
|
|
3
|
+
safeStringify,
|
|
4
|
+
sideEffectsEnabled,
|
|
5
|
+
generateRandomID,
|
|
6
|
+
} from "../utils/index.js"
|
|
2
7
|
import { $HMR_ACCEPT, $SIGNAL } from "../constants.js"
|
|
3
8
|
import { __DEV__ } from "../env.js"
|
|
4
9
|
import { node } from "../globals.js"
|
|
5
10
|
import { useHook } from "../hooks/utils.js"
|
|
6
|
-
import { generateRandomID } from "../generateId.js"
|
|
7
11
|
import { requestUpdate } from "../scheduler.js"
|
|
8
12
|
import { tracking, signalSubsMap } from "./globals.js"
|
|
9
13
|
import type { SignalSubscriber, ReadonlySignal } from "./types.js"
|
package/src/signals/computed.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __DEV__ } from "../env.js"
|
|
2
2
|
import { $HMR_ACCEPT } from "../constants.js"
|
|
3
3
|
import { useHook } from "../hooks/utils.js"
|
|
4
|
-
import { latest } from "../utils.js"
|
|
4
|
+
import { latest } from "../utils/index.js"
|
|
5
5
|
import { effectQueue, signalSubsMap } from "./globals.js"
|
|
6
6
|
import { executeWithTracking } from "./effect.js"
|
|
7
7
|
import { Signal } from "./base.js"
|
package/src/signals/effect.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { node } from "../globals.js"
|
|
2
|
-
import { sideEffectsEnabled } from "../utils.js"
|
|
2
|
+
import { sideEffectsEnabled } from "../utils/index.js"
|
|
3
3
|
import { tracking, effectQueue } from "./globals.js"
|
|
4
4
|
import { tick } from "./utils.js"
|
|
5
5
|
import type { Signal } from "./base.js"
|
package/src/signals/watch.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { __DEV__ } from "../env.js"
|
|
2
2
|
import type { HMRAccept } from "../hmr.js"
|
|
3
3
|
import { $HMR_ACCEPT } from "../constants.js"
|
|
4
|
-
import {
|
|
4
|
+
import { useHook } from "../hooks/utils.js"
|
|
5
5
|
import { effectQueue } from "./globals.js"
|
|
6
|
-
import { generateRandomID } from "../generateId.js"
|
|
7
6
|
import { executeWithTracking } from "./effect.js"
|
|
8
|
-
import { latest } from "../utils.js"
|
|
7
|
+
import { latest, sideEffectsEnabled, generateRandomID } from "../utils/index.js"
|
|
9
8
|
import type { Signal } from "./base.js"
|
|
10
9
|
import type { SignalValues } from "./types.js"
|
|
11
10
|
|
package/src/ssr/server.ts
CHANGED
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
encodeHtmlEntities,
|
|
7
7
|
propsToElementAttributes,
|
|
8
8
|
isExoticType,
|
|
9
|
-
|
|
9
|
+
assertValidElementProps,
|
|
10
|
+
} from "../utils/index.js"
|
|
10
11
|
import { Signal } from "../signals/base.js"
|
|
11
12
|
import { $HYDRATION_BOUNDARY, voidElements } from "../constants.js"
|
|
12
|
-
import { assertValidElementProps } from "../props.js"
|
|
13
13
|
import { HYDRATION_BOUNDARY_MARKER } from "./hydrationBoundary.js"
|
|
14
14
|
import { __DEV__ } from "../env.js"
|
|
15
15
|
|
package/src/store.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import type { Prettify } from "./types.utils.js"
|
|
2
2
|
import { __DEV__ } from "./env.js"
|
|
3
|
-
import {
|
|
4
|
-
import { safeStringify, shallowCompare } from "./utils.js"
|
|
3
|
+
import { useHook } from "./hooks/utils.js"
|
|
5
4
|
import { $HMR_ACCEPT } from "./constants.js"
|
|
6
5
|
import { HMRAccept } from "./hmr.js"
|
|
6
|
+
import {
|
|
7
|
+
safeStringify,
|
|
8
|
+
shallowCompare,
|
|
9
|
+
sideEffectsEnabled,
|
|
10
|
+
} from "./utils/index.js"
|
|
7
11
|
|
|
8
12
|
export { createStore }
|
|
9
13
|
export type { Store, MethodFactory }
|
package/src/swr.ts
CHANGED
|
@@ -3,12 +3,12 @@ import { useHook } from "./hooks/utils.js"
|
|
|
3
3
|
import { Signal } from "./signals/base.js"
|
|
4
4
|
import { AsyncTaskState } from "./types.utils.js"
|
|
5
5
|
import {
|
|
6
|
-
noop,
|
|
7
6
|
deepCompare,
|
|
7
|
+
noop,
|
|
8
8
|
safeStringify,
|
|
9
|
-
sideEffectsEnabled,
|
|
10
9
|
shallowCompare,
|
|
11
|
-
|
|
10
|
+
sideEffectsEnabled,
|
|
11
|
+
} from "./utils/index.js"
|
|
12
12
|
|
|
13
13
|
export type UseSWRState<T> = AsyncTaskState<T, UseSWRError> & {
|
|
14
14
|
mutate: (callback: () => Promise<T>) => void
|
package/src/types.dom.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Signal } from "./signals"
|
|
1
|
+
import type { Signal } from "./signals"
|
|
2
2
|
import type { Prettify, Signalable } from "./types.utils"
|
|
3
3
|
|
|
4
4
|
export type {
|
|
@@ -60,6 +60,7 @@ type NumericStyleKeys =
|
|
|
60
60
|
| "width"
|
|
61
61
|
|
|
62
62
|
// Flexbox
|
|
63
|
+
| "flex"
|
|
63
64
|
| "flexBasis"
|
|
64
65
|
| "flexGrow"
|
|
65
66
|
| "flexShrink"
|
package/src/types.ts
CHANGED
|
@@ -16,7 +16,12 @@ import type {
|
|
|
16
16
|
HTMLTagToElement,
|
|
17
17
|
SVGTagToElement,
|
|
18
18
|
} from "./types.dom"
|
|
19
|
-
import {
|
|
19
|
+
import type {
|
|
20
|
+
AsyncTaskState,
|
|
21
|
+
Prettify,
|
|
22
|
+
Signalable,
|
|
23
|
+
SomeDom,
|
|
24
|
+
} from "./types.utils"
|
|
20
25
|
import type { AppContext } from "./appContext"
|
|
21
26
|
|
|
22
27
|
export type { AsyncTaskState, ElementProps, Prettify, Signalable, StyleObject }
|
|
@@ -128,10 +133,12 @@ declare global {
|
|
|
128
133
|
displayName?: string
|
|
129
134
|
}
|
|
130
135
|
|
|
131
|
-
|
|
136
|
+
interface FC<T = {}> {
|
|
137
|
+
(props: FCProps<T>): JSX.Element
|
|
132
138
|
/** Used to display the name of the component in devtools */
|
|
133
139
|
displayName?: string
|
|
134
140
|
}
|
|
141
|
+
|
|
135
142
|
type FCProps<T = {}> = T & { children?: JSX.Children }
|
|
136
143
|
type InferProps<T> = T extends Kiru.FC<infer P> ? P : never
|
|
137
144
|
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
export function deepCompare<T>(a: T, b: T): boolean {
|
|
2
|
+
return compare(a, b, true)
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function shallowCompare<T>(a: T, b: T): boolean {
|
|
6
|
+
return compare(a, b, false)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function compare<T>(a: T, b: T, deep = false): boolean {
|
|
10
|
+
// Fast path: identity comparison
|
|
11
|
+
if (a === b) return true
|
|
12
|
+
|
|
13
|
+
// Handle primitive types and null/undefined
|
|
14
|
+
if (
|
|
15
|
+
a == null ||
|
|
16
|
+
b == null ||
|
|
17
|
+
typeof a !== "object" ||
|
|
18
|
+
typeof b !== "object"
|
|
19
|
+
) {
|
|
20
|
+
return false
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Handle arrays efficiently
|
|
24
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
25
|
+
if (a.length !== b.length) return false
|
|
26
|
+
|
|
27
|
+
if (deep) {
|
|
28
|
+
for (let i = 0; i < a.length; i++) {
|
|
29
|
+
if (!compare(a[i], b[i], true)) return false
|
|
30
|
+
}
|
|
31
|
+
} else {
|
|
32
|
+
for (let i = 0; i < a.length; i++) {
|
|
33
|
+
if (!Object.is(a[i], b[i])) return false
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return true
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Handle Maps
|
|
40
|
+
if (a instanceof Map && b instanceof Map) {
|
|
41
|
+
if (a.size !== b.size) return false
|
|
42
|
+
|
|
43
|
+
for (const [key, valueA] of a) {
|
|
44
|
+
if (!b.has(key)) return false
|
|
45
|
+
|
|
46
|
+
const valueB = b.get(key)
|
|
47
|
+
if (deep) {
|
|
48
|
+
if (!compare(valueA, valueB, true)) return false
|
|
49
|
+
} else {
|
|
50
|
+
if (!Object.is(valueA, valueB)) return false
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return true
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Handle Sets more efficiently
|
|
57
|
+
if (a instanceof Set && b instanceof Set) {
|
|
58
|
+
if (a.size !== b.size) return false
|
|
59
|
+
|
|
60
|
+
if (deep) {
|
|
61
|
+
// For deep equality of Sets, we need to compare the values themselves
|
|
62
|
+
// Convert to arrays and sort for comparison
|
|
63
|
+
const aValues = Array.from(a)
|
|
64
|
+
const bValues = Array.from(b)
|
|
65
|
+
|
|
66
|
+
if (aValues.length !== bValues.length) return false
|
|
67
|
+
|
|
68
|
+
// Simple compare doesn't work for objects in Sets with deep comparison
|
|
69
|
+
// Using a matching algorithm instead
|
|
70
|
+
for (const valueA of aValues) {
|
|
71
|
+
// Find matching element in bValues
|
|
72
|
+
let found = false
|
|
73
|
+
for (let i = 0; i < bValues.length; i++) {
|
|
74
|
+
if (compare(valueA, bValues[i], true)) {
|
|
75
|
+
bValues.splice(i, 1) // Remove the matched element
|
|
76
|
+
found = true
|
|
77
|
+
break
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (!found) return false
|
|
81
|
+
}
|
|
82
|
+
return true
|
|
83
|
+
} else {
|
|
84
|
+
// Regular Set comparison
|
|
85
|
+
for (const valueA of a) {
|
|
86
|
+
if (!b.has(valueA)) return false
|
|
87
|
+
}
|
|
88
|
+
return true
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Handle Date objects
|
|
93
|
+
if (a instanceof Date && b instanceof Date) {
|
|
94
|
+
return a.getTime() === b.getTime()
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Handle RegExp objects
|
|
98
|
+
if (a instanceof RegExp && b instanceof RegExp) {
|
|
99
|
+
return a.toString() === b.toString()
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Handle plain objects
|
|
103
|
+
const keysA = Object.keys(a)
|
|
104
|
+
const keysB = Object.keys(b)
|
|
105
|
+
|
|
106
|
+
if (keysA.length !== keysB.length) return false
|
|
107
|
+
|
|
108
|
+
// Use a Set for faster key lookup
|
|
109
|
+
const keySet = new Set(keysB)
|
|
110
|
+
|
|
111
|
+
for (const key of keysA) {
|
|
112
|
+
if (!keySet.has(key)) return false
|
|
113
|
+
|
|
114
|
+
const valueA = a[key as keyof T]
|
|
115
|
+
const valueB = b[key as keyof T]
|
|
116
|
+
|
|
117
|
+
if (deep) {
|
|
118
|
+
if (!compare(valueA, valueB, true)) return false
|
|
119
|
+
} else {
|
|
120
|
+
if (!Object.is(valueA, valueB)) return false
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return true
|
|
125
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { unwrap } from "../signals/index.js"
|
|
2
|
+
import {
|
|
3
|
+
booleanAttributes,
|
|
4
|
+
REGEX_UNIT,
|
|
5
|
+
snakeCaseAttributes,
|
|
6
|
+
} from "../constants.js"
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
className,
|
|
10
|
+
encodeHtmlEntities,
|
|
11
|
+
propFilters,
|
|
12
|
+
propToHtmlAttr,
|
|
13
|
+
styleObjectToString,
|
|
14
|
+
propValueToHtmlAttrValue,
|
|
15
|
+
propsToElementAttributes,
|
|
16
|
+
safeStringify,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function className(...classes: (string | false | null | undefined)[]): string {
|
|
20
|
+
return classes.filter(Boolean).join(" ")
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function encodeHtmlEntities(text: string): string {
|
|
24
|
+
return text
|
|
25
|
+
.replace(REGEX_UNIT.AMP_G, "&")
|
|
26
|
+
.replace(REGEX_UNIT.LT_G, "<")
|
|
27
|
+
.replace(REGEX_UNIT.GT_G, ">")
|
|
28
|
+
.replace(REGEX_UNIT.DBLQT_G, """)
|
|
29
|
+
.replace(REGEX_UNIT.SQT_G, "'")
|
|
30
|
+
.replace(REGEX_UNIT.SLASH_G, "/")
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const propFilters = {
|
|
34
|
+
internalProps: ["children", "ref", "key", "innerHTML"],
|
|
35
|
+
isEvent: (key: string) => key.startsWith("on"),
|
|
36
|
+
isProperty: (key: string) =>
|
|
37
|
+
!propFilters.internalProps.includes(key) && !propFilters.isEvent(key),
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function propToHtmlAttr(key: string): string {
|
|
41
|
+
switch (key) {
|
|
42
|
+
case "className":
|
|
43
|
+
return "class"
|
|
44
|
+
case "htmlFor":
|
|
45
|
+
return "for"
|
|
46
|
+
case "tabIndex":
|
|
47
|
+
case "formAction":
|
|
48
|
+
case "formMethod":
|
|
49
|
+
case "formEncType":
|
|
50
|
+
case "contentEditable":
|
|
51
|
+
case "spellCheck":
|
|
52
|
+
case "allowFullScreen":
|
|
53
|
+
case "autoPlay":
|
|
54
|
+
case "disablePictureInPicture":
|
|
55
|
+
case "disableRemotePlayback":
|
|
56
|
+
case "formNoValidate":
|
|
57
|
+
case "noModule":
|
|
58
|
+
case "noValidate":
|
|
59
|
+
case "popoverTarget":
|
|
60
|
+
case "popoverTargetAction":
|
|
61
|
+
case "playsInline":
|
|
62
|
+
case "readOnly":
|
|
63
|
+
case "itemscope":
|
|
64
|
+
case "rowSpan":
|
|
65
|
+
case "crossOrigin":
|
|
66
|
+
return key.toLowerCase()
|
|
67
|
+
|
|
68
|
+
default:
|
|
69
|
+
if (key.indexOf("-") > -1) return key
|
|
70
|
+
if (key.startsWith("aria"))
|
|
71
|
+
return "aria-" + key.substring(4).toLowerCase()
|
|
72
|
+
|
|
73
|
+
return snakeCaseAttributes.get(key) || key
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function styleObjectToString(obj: Partial<CSSStyleDeclaration>): string {
|
|
78
|
+
let cssString = ""
|
|
79
|
+
for (const key in obj) {
|
|
80
|
+
const cssKey = key.replace(REGEX_UNIT.ALPHA_UPPER_G, "-$&").toLowerCase()
|
|
81
|
+
cssString += `${cssKey}:${obj[key]};`
|
|
82
|
+
}
|
|
83
|
+
return cssString
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function stylePropToString(style: unknown) {
|
|
87
|
+
if (typeof style === "string") return style
|
|
88
|
+
if (typeof style === "object" && !!style) return styleObjectToString(style)
|
|
89
|
+
return ""
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function propValueToHtmlAttrValue(key: string, value: unknown): string {
|
|
93
|
+
return key === "style" && typeof value === "object" && !!value
|
|
94
|
+
? styleObjectToString(value)
|
|
95
|
+
: String(value)
|
|
96
|
+
}
|
|
97
|
+
function propsToElementAttributes(props: Record<string, unknown>): string {
|
|
98
|
+
const attrs: string[] = []
|
|
99
|
+
const { className, style, ...rest } = props
|
|
100
|
+
if (className) {
|
|
101
|
+
const val = unwrap(className)
|
|
102
|
+
if (!!val) attrs.push(`class="${val}"`)
|
|
103
|
+
}
|
|
104
|
+
if (style) {
|
|
105
|
+
const val = unwrap(style)
|
|
106
|
+
if (!!val) attrs.push(`style="${stylePropToString(val)}"`)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const keys = Object.keys(rest).filter(propFilters.isProperty)
|
|
110
|
+
for (let i = 0; i < keys.length; i++) {
|
|
111
|
+
let k = keys[i]
|
|
112
|
+
let val = unwrap(props[k])
|
|
113
|
+
if (val === null || val === undefined) continue
|
|
114
|
+
|
|
115
|
+
k = k.split("bind:")[1] ?? k // normalize bind props
|
|
116
|
+
const key = propToHtmlAttr(k)
|
|
117
|
+
|
|
118
|
+
switch (typeof val) {
|
|
119
|
+
case "function":
|
|
120
|
+
case "symbol":
|
|
121
|
+
continue
|
|
122
|
+
case "boolean":
|
|
123
|
+
if (booleanAttributes.has(key)) {
|
|
124
|
+
if (val) attrs.push(key)
|
|
125
|
+
continue
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
attrs.push(`${key}="${val}"`)
|
|
129
|
+
}
|
|
130
|
+
return attrs.join(" ")
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
type SafeStringifyOptions = {
|
|
134
|
+
/**
|
|
135
|
+
* By default, functions are stringified. Specify `false` to instead produce `[FUNCTION (${fn.name})]`.
|
|
136
|
+
*/
|
|
137
|
+
functions: boolean
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function safeStringify(
|
|
141
|
+
value: unknown,
|
|
142
|
+
opts: SafeStringifyOptions = { functions: true }
|
|
143
|
+
): string {
|
|
144
|
+
const seen = new WeakSet()
|
|
145
|
+
return JSON.stringify(value, (_, value) => {
|
|
146
|
+
if (typeof value === "object" && value !== null) {
|
|
147
|
+
if (seen.has(value)) {
|
|
148
|
+
return "[CIRCULAR]"
|
|
149
|
+
}
|
|
150
|
+
seen.add(value)
|
|
151
|
+
}
|
|
152
|
+
if (typeof value === "function") {
|
|
153
|
+
if (!opts.functions) return `[FUNCTION (${value.name || "anonymous"})]`
|
|
154
|
+
return value.toString()
|
|
155
|
+
}
|
|
156
|
+
return value
|
|
157
|
+
})
|
|
158
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { __DEV__ } from "../env.js"
|
|
2
|
+
import { renderMode } from "../globals.js"
|
|
3
|
+
|
|
4
|
+
export { latest, sideEffectsEnabled }
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* This is a no-op in production. It is used to get the latest
|
|
8
|
+
* iteration of a component or signal after HMR has happened.
|
|
9
|
+
*/
|
|
10
|
+
function latest<T>(thing: T): T {
|
|
11
|
+
let tgt: any = thing
|
|
12
|
+
if (__DEV__) {
|
|
13
|
+
while ("__next" in tgt) {
|
|
14
|
+
tgt = tgt.__next as typeof tgt
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return tgt
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Returns false if called during "stream" or "string" render modes.
|
|
22
|
+
*/
|
|
23
|
+
function sideEffectsEnabled(): boolean {
|
|
24
|
+
return renderMode.current === "dom" || renderMode.current === "hydrate"
|
|
25
|
+
}
|