@tanstack/redact 0.0.21 → 0.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/core/attributes.js +2 -1
- package/dist/core/attributes.js.map +2 -2
- package/dist/core/browser.d.ts +9 -0
- package/dist/core/browser.js +35 -0
- package/dist/core/browser.js.map +7 -0
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +3 -3
- package/dist/core/internal.d.ts +31 -8
- package/dist/core/internal.js +3 -1
- package/dist/core/internal.js.map +2 -2
- package/dist/core/resource-hints.d.ts +7 -0
- package/dist/core/resource-hints.js +19 -0
- package/dist/core/resource-hints.js.map +7 -0
- package/dist/core/types.js +1 -1
- package/dist/dom/_all.d.ts +11 -16
- package/dist/dom/_all.js +9 -20
- package/dist/dom/_all.js.map +2 -2
- package/dist/dom/client.d.ts +4 -4
- package/dist/dom/client.js +4 -4
- package/dist/dom/commit.d.ts +23 -0
- package/dist/dom/commit.js +191 -0
- package/dist/dom/commit.js.map +7 -0
- package/dist/dom/dispatcher.d.ts +4 -22
- package/dist/dom/dispatcher.js +184 -126
- package/dist/dom/dispatcher.js.map +3 -3
- package/dist/dom/dom.d.ts +2 -0
- package/dist/dom/dom.js +72 -52
- package/dist/dom/dom.js.map +2 -2
- package/dist/dom/error-info.d.ts +2 -0
- package/dist/dom/error-info.js +16 -0
- package/dist/dom/error-info.js.map +7 -0
- package/dist/dom/event-replay.js +1 -1
- package/dist/dom/features/activity/full.d.ts +1 -0
- package/dist/dom/features/activity/full.js +162 -0
- package/dist/dom/features/activity/full.js.map +7 -0
- package/dist/dom/features/activity/index.d.ts +1 -0
- package/dist/dom/features/activity/index.js +3 -0
- package/dist/dom/features/activity/index.js.map +7 -0
- package/dist/dom/features/activity/stub.d.ts +1 -0
- package/dist/dom/features/activity/stub.js +12 -0
- package/dist/dom/features/activity/stub.js.map +7 -0
- package/dist/dom/features/class/full.js +87 -27
- package/dist/dom/features/class/full.js.map +2 -2
- package/dist/dom/features/class/index.d.ts +1 -1
- package/dist/dom/features/class/index.js +2 -2
- package/dist/dom/features/class/stub.js +3 -3
- package/dist/dom/features/context/full.d.ts +4 -1
- package/dist/dom/features/context/full.js +69 -9
- package/dist/dom/features/context/full.js.map +2 -2
- package/dist/dom/features/context/index.d.ts +1 -1
- package/dist/dom/features/context/index.js +2 -2
- package/dist/dom/features/context/stub.d.ts +4 -1
- package/dist/dom/features/context/stub.js +15 -4
- package/dist/dom/features/context/stub.js.map +2 -2
- package/dist/dom/features/forward-ref/full.js +12 -21
- package/dist/dom/features/forward-ref/full.js.map +2 -2
- package/dist/dom/features/forward-ref/index.d.ts +1 -1
- package/dist/dom/features/forward-ref/index.js +2 -2
- package/dist/dom/features/forward-ref/stub.js +4 -4
- package/dist/dom/features/fragment-refs/index.d.ts +1 -0
- package/dist/dom/features/fragment-refs/index.js +8 -0
- package/dist/dom/features/fragment-refs/index.js.map +7 -0
- package/dist/dom/features/fragment-refs/stub.d.ts +3 -0
- package/dist/dom/features/fragment-refs/stub.js +14 -0
- package/dist/dom/features/fragment-refs/stub.js.map +7 -0
- package/dist/dom/features/hydration/full.d.ts +11 -6
- package/dist/dom/features/hydration/full.js +76 -77
- package/dist/dom/features/hydration/full.js.map +2 -2
- package/dist/dom/features/hydration/index.d.ts +1 -1
- package/dist/dom/features/hydration/index.js +2 -2
- package/dist/dom/features/hydration/stub.d.ts +7 -2
- package/dist/dom/features/hydration/stub.js +1 -1
- package/dist/dom/features/hydration/stub.js.map +1 -1
- package/dist/dom/features/index.d.ts +8 -7
- package/dist/dom/features/index.js +9 -8
- package/dist/dom/features/index.js.map +2 -2
- package/dist/dom/features/lazy/full.js +4 -4
- package/dist/dom/features/lazy/index.d.ts +1 -1
- package/dist/dom/features/lazy/index.js +2 -2
- package/dist/dom/features/lazy/stub.js +4 -4
- package/dist/dom/features/memo/full.js +8 -6
- package/dist/dom/features/memo/full.js.map +2 -2
- package/dist/dom/features/memo/index.d.ts +1 -1
- package/dist/dom/features/memo/index.js +2 -2
- package/dist/dom/features/memo/stub.js +4 -4
- package/dist/dom/features/portal/full.js +4 -4
- package/dist/dom/features/portal/index.d.ts +1 -1
- package/dist/dom/features/portal/index.js +2 -2
- package/dist/dom/features/portal/stub.js +4 -4
- package/dist/dom/features/suspense/full.js +197 -52
- package/dist/dom/features/suspense/full.js.map +2 -2
- package/dist/dom/features/suspense/index.d.ts +1 -1
- package/dist/dom/features/suspense/index.js +2 -2
- package/dist/dom/features/suspense/stub.js +4 -4
- package/dist/dom/features/view-transition/full.d.ts +6 -0
- package/dist/dom/features/view-transition/full.js +280 -0
- package/dist/dom/features/view-transition/full.js.map +7 -0
- package/dist/dom/features/view-transition/index.d.ts +1 -0
- package/dist/dom/features/view-transition/index.js +3 -0
- package/dist/dom/features/view-transition/index.js.map +7 -0
- package/dist/dom/features/view-transition/resources.d.ts +11 -0
- package/dist/dom/features/view-transition/resources.js +108 -0
- package/dist/dom/features/view-transition/resources.js.map +7 -0
- package/dist/dom/features/view-transition/stub.d.ts +6 -0
- package/dist/dom/features/view-transition/stub.js +22 -0
- package/dist/dom/features/view-transition/stub.js.map +7 -0
- package/dist/dom/features/view-transition/visual.d.ts +14 -0
- package/dist/dom/features/view-transition/visual.js +356 -0
- package/dist/dom/features/view-transition/visual.js.map +7 -0
- package/dist/dom/fragment-instance.d.ts +40 -0
- package/dist/dom/fragment-instance.js +324 -0
- package/dist/dom/fragment-instance.js.map +7 -0
- package/dist/dom/index.d.ts +11 -11
- package/dist/dom/index.js +11 -18
- package/dist/dom/index.js.map +3 -3
- package/dist/dom/portal.d.ts +2 -2
- package/dist/dom/portal.js +2 -2
- package/dist/dom/portal.js.map +1 -1
- package/dist/dom/reconcile.d.ts +32 -3
- package/dist/dom/reconcile.js +689 -221
- package/dist/dom/reconcile.js.map +2 -2
- package/dist/dom/resource-hints.d.ts +6 -0
- package/dist/dom/resource-hints.js +115 -0
- package/dist/dom/resource-hints.js.map +7 -0
- package/dist/dom/resource-store.d.ts +13 -0
- package/dist/dom/resource-store.js +43 -0
- package/dist/dom/resource-store.js.map +7 -0
- package/dist/dom/resources.d.ts +1 -0
- package/dist/dom/resources.js +44 -0
- package/dist/dom/resources.js.map +7 -0
- package/dist/dom/retained-effects.d.ts +6 -0
- package/dist/dom/retained-effects.js +49 -0
- package/dist/dom/retained-effects.js.map +7 -0
- package/dist/dom/root-internal.d.ts +4 -4
- package/dist/dom/root-internal.js +2 -2
- package/dist/dom/root-internal.js.map +2 -2
- package/dist/dom/root.d.ts +5 -5
- package/dist/dom/root.js +11 -11
- package/dist/dom/root.js.map +2 -2
- package/dist/dom/test-utils.js +1 -1
- package/dist/react/activity.d.ts +7 -0
- package/dist/react/activity.js +8 -0
- package/dist/react/activity.js.map +7 -0
- package/dist/react/children.d.ts +1 -1
- package/dist/react/children.js +3 -3
- package/dist/react/children.js.map +1 -1
- package/dist/react/class.d.ts +1 -1
- package/dist/react/class.js +3 -3
- package/dist/react/class.js.map +1 -1
- package/dist/react/compiler-runtime.js +2 -2
- package/dist/react/context.d.ts +1 -1
- package/dist/react/context.js +3 -3
- package/dist/react/context.js.map +1 -1
- package/dist/react/element.d.ts +6 -3
- package/dist/react/element.js +2 -2
- package/dist/react/element.js.map +2 -2
- package/dist/react/hooks.d.ts +26 -7
- package/dist/react/hooks.js +13 -3
- package/dist/react/hooks.js.map +2 -2
- package/dist/react/index.d.ts +39 -24
- package/dist/react/index.js +39 -19
- package/dist/react/index.js.map +3 -3
- package/dist/react/jsx-runtime.d.ts +2 -2
- package/dist/react/jsx-runtime.js +3 -3
- package/dist/react/memo.d.ts +1 -1
- package/dist/react/memo.js +1 -1
- package/dist/react/portal.js +1 -1
- package/dist/react/shared-internals.d.ts +15 -5
- package/dist/react/shared-internals.js +2 -3
- package/dist/react/shared-internals.js.map +2 -2
- package/dist/react/suspense.js +1 -1
- package/dist/react/view-transition.d.ts +32 -0
- package/dist/react/view-transition.js +13 -0
- package/dist/react/view-transition.js.map +7 -0
- package/dist/scheduler/index.js +1 -1
- package/dist/server/bootstrap-script.d.ts +1 -23
- package/dist/server/bootstrap-script.js +7 -6
- package/dist/server/bootstrap-script.js.map +2 -2
- package/dist/server/dispatcher.d.ts +28 -6
- package/dist/server/dispatcher.js +33 -15
- package/dist/server/dispatcher.js.map +2 -2
- package/dist/server/escape.js +16 -15
- package/dist/server/escape.js.map +2 -2
- package/dist/server/index.d.ts +6 -6
- package/dist/server/index.js +7 -7
- package/dist/server/renderToString.d.ts +1 -1
- package/dist/server/renderToString.js +12 -8
- package/dist/server/renderToString.js.map +2 -2
- package/dist/server/resource-hints.d.ts +22 -0
- package/dist/server/resource-hints.js +148 -0
- package/dist/server/resource-hints.js.map +7 -0
- package/dist/server/stream.d.ts +15 -2
- package/dist/server/stream.js +155 -63
- package/dist/server/stream.js.map +2 -2
- package/dist/server/walk.d.ts +15 -2
- package/dist/server/walk.js +143 -96
- package/dist/server/walk.js.map +2 -2
- package/dist/vite/index.d.ts +6 -0
- package/dist/vite/index.js +22 -6
- package/dist/vite/index.js.map +2 -2
- package/package.json +1 -1
- package/src/core/attributes.ts +1 -0
- package/src/core/browser.ts +33 -0
- package/src/core/internal.ts +24 -6
- package/src/core/resource-hints.ts +36 -0
- package/src/dom/_all.ts +1 -7
- package/src/dom/commit.ts +186 -0
- package/src/dom/dispatcher.ts +190 -134
- package/src/dom/dom.ts +70 -54
- package/src/dom/error-info.ts +15 -0
- package/src/dom/features/activity/full.ts +166 -0
- package/src/dom/features/activity/index.ts +1 -0
- package/src/dom/features/activity/stub.ts +14 -0
- package/src/dom/features/class/full.ts +72 -28
- package/src/dom/features/context/full.ts +66 -4
- package/src/dom/features/context/stub.ts +6 -0
- package/src/dom/features/forward-ref/full.ts +9 -19
- package/src/dom/features/fragment-refs/index.ts +1 -0
- package/src/dom/features/fragment-refs/stub.ts +3 -0
- package/src/dom/features/hydration/full.ts +84 -85
- package/src/dom/features/hydration/stub.ts +1 -1
- package/src/dom/features/index.ts +1 -0
- package/src/dom/features/memo/full.ts +4 -3
- package/src/dom/features/suspense/full.ts +192 -55
- package/src/dom/features/view-transition/full.ts +288 -0
- package/src/dom/features/view-transition/index.ts +1 -0
- package/src/dom/features/view-transition/resources.ts +107 -0
- package/src/dom/features/view-transition/stub.ts +7 -0
- package/src/dom/features/view-transition/visual.ts +406 -0
- package/src/dom/fragment-instance.ts +337 -0
- package/src/dom/index.ts +6 -7
- package/src/dom/portal.ts +1 -1
- package/src/dom/reconcile.ts +695 -242
- package/src/dom/resource-hints.ts +115 -0
- package/src/dom/resource-store.ts +52 -0
- package/src/dom/resources.ts +39 -0
- package/src/dom/retained-effects.ts +38 -0
- package/src/dom/root-internal.ts +4 -4
- package/src/dom/root.ts +12 -14
- package/src/react/activity.ts +10 -0
- package/src/react/element.ts +6 -2
- package/src/react/hooks.ts +12 -3
- package/src/react/index.ts +18 -0
- package/src/react/shared-internals.ts +3 -3
- package/src/react/view-transition.ts +41 -0
- package/src/server/bootstrap-script.ts +36 -5
- package/src/server/dispatcher.ts +35 -13
- package/src/server/escape.ts +15 -12
- package/src/server/renderToString.ts +7 -5
- package/src/server/resource-hints.ts +165 -0
- package/src/server/stream.ts +154 -62
- package/src/server/walk.ts +72 -11
- package/src/vite/index.ts +30 -13
package/src/dom/dispatcher.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import type { Hook, Fiber, FiberRoot, Effect } from '../core'
|
|
2
|
-
import { ReactSharedInternals, REACT_CONTEXT_TYPE } from '../react'
|
|
3
|
-
import { scheduleUpdate, enqueueEffect, readContext } from './reconcile'
|
|
1
|
+
import type { Hook, Fiber, FiberRoot, Effect, ReactNode } from '../core'
|
|
2
|
+
import { ReactSharedInternals, REACT_CONTEXT_TYPE, startTransition } from '../react'
|
|
3
|
+
import { scheduleUpdate, enqueueEffect, readContext, rememberActivityEffect, handleCommitError } from './reconcile'
|
|
4
|
+
import { REACT_RECOVERABLE_TYPE } from '../core/browser'
|
|
5
|
+
import { queueCommitEffects } from './commit'
|
|
6
|
+
import { deferTransitionPassive } from './features/view-transition'
|
|
4
7
|
|
|
5
8
|
function getCurrentFiber(): Fiber {
|
|
6
9
|
const f = ReactSharedInternals.F
|
|
@@ -14,32 +17,9 @@ function getCurrentFiber(): Fiber {
|
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
function nextHook(): Hook {
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
let prev = ReactSharedInternals.K
|
|
21
|
-
|
|
22
|
-
if (idx === 0) {
|
|
23
|
-
if (fiber.hooks) {
|
|
24
|
-
ReactSharedInternals.K = fiber.hooks
|
|
25
|
-
return fiber.hooks
|
|
26
|
-
}
|
|
27
|
-
const h: Hook = { s: undefined, q: undefined, d: undefined, c: undefined, n: null }
|
|
28
|
-
fiber.hooks = h
|
|
29
|
-
ReactSharedInternals.K = h
|
|
30
|
-
return h
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (prev && prev.n) {
|
|
34
|
-
ReactSharedInternals.K = prev.n
|
|
35
|
-
return prev.n
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const h: Hook = { s: undefined, q: undefined, d: undefined, c: undefined, n: null }
|
|
39
|
-
if (prev) prev.n = h
|
|
40
|
-
else fiber.hooks = h
|
|
41
|
-
ReactSharedInternals.K = h
|
|
42
|
-
return h
|
|
20
|
+
const hooks = getCurrentFiber().hooks ||= []
|
|
21
|
+
const index = ReactSharedInternals.I++
|
|
22
|
+
return hooks[index] ||= { s: undefined, q: undefined, d: undefined, c: undefined }
|
|
43
23
|
}
|
|
44
24
|
|
|
45
25
|
function depsEqual(
|
|
@@ -57,110 +37,185 @@ function depsEqual(
|
|
|
57
37
|
|
|
58
38
|
type BasicStateAction<S> = S | ((p: S) => S)
|
|
59
39
|
|
|
40
|
+
function initializeReducer(hook: Hook, fiber: Fiber, initialArg: any, init?: (arg: any) => any): void {
|
|
41
|
+
hook.s = init ? init(initialArg) : initialArg
|
|
42
|
+
hook.c = null
|
|
43
|
+
hook.q = (action: any) => {
|
|
44
|
+
if (fiber.um || fiber.pd) return
|
|
45
|
+
;(hook.c ||= []).push(action)
|
|
46
|
+
scheduleUpdate(fiber)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Reducer slots reuse the effect-cleanup field for pending actions. Zero marks
|
|
51
|
+
// eager state work, null means no update. Replacing arrays lets retries restore
|
|
52
|
+
// pending actions without copying or shifting them.
|
|
53
|
+
function reducePending(hook: Hook, reducer: (state: any, action: any) => any, previous = hook.s): void {
|
|
54
|
+
const actions = hook.c
|
|
55
|
+
if (actions == null) return
|
|
56
|
+
hook.c = null
|
|
57
|
+
let state = hook.s
|
|
58
|
+
if (actions) for (const action of actions) state = reducer(state, action)
|
|
59
|
+
hookFlags |= Object.is(state, previous) ? 2 : 3
|
|
60
|
+
hook.s = state
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let hookEffects: any[] | undefined
|
|
64
|
+
// Bit 1 records a changed value; bit 2 records a processed reducer queue.
|
|
65
|
+
let hookFlags = 0
|
|
66
|
+
export const HOOK_BAILOUT = Symbol()
|
|
67
|
+
|
|
68
|
+
function resetHookEffects(effects: any[]): void {
|
|
69
|
+
for (let index = 0; index < effects.length; index += 4) effects[index].d = effects[index + 1]
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function renderWithHooks(
|
|
73
|
+
fiber: Fiber,
|
|
74
|
+
render: (props: any, ref?: any) => ReactNode,
|
|
75
|
+
props: any,
|
|
76
|
+
ref?: any,
|
|
77
|
+
canBail = false,
|
|
78
|
+
): ReactNode | typeof HOOK_BAILOUT {
|
|
79
|
+
const previousDispatcher = ReactSharedInternals.H, previousFiber = ReactSharedInternals.F, previousIndex = ReactSharedInternals.I
|
|
80
|
+
const previousEffects = hookEffects, previousFlags = hookFlags
|
|
81
|
+
hookEffects = undefined
|
|
82
|
+
hookFlags = 0
|
|
83
|
+
ReactSharedInternals.H = DISPATCHER
|
|
84
|
+
ReactSharedInternals.F = fiber
|
|
85
|
+
try {
|
|
86
|
+
let rendered: ReactNode, attempts = 0
|
|
87
|
+
do {
|
|
88
|
+
if (++attempts > 25) throw new Error(process.env.NODE_ENV !== 'production' ? 'Too many re-renders.' : '')
|
|
89
|
+
if (hookEffects) {
|
|
90
|
+
resetHookEffects(hookEffects)
|
|
91
|
+
hookEffects = undefined
|
|
92
|
+
}
|
|
93
|
+
ReactSharedInternals.I = 0
|
|
94
|
+
fiber.dy = false
|
|
95
|
+
rendered = render(props, ref)
|
|
96
|
+
} while (fiber.dy)
|
|
97
|
+
if (canBail && hookFlags === 2) {
|
|
98
|
+
// React accepts the rendered dependencies on a reducer bailout, but
|
|
99
|
+
// keeps the previous committed effect descriptions until real work.
|
|
100
|
+
hookEffects = undefined
|
|
101
|
+
return HOOK_BAILOUT
|
|
102
|
+
}
|
|
103
|
+
if (hookEffects) {
|
|
104
|
+
const effects: any[] = hookEffects
|
|
105
|
+
for (let index = 0; index < effects.length; index += 4) {
|
|
106
|
+
const hook = effects[index], effect = effects[index + 2]
|
|
107
|
+
rememberActivityEffect(fiber, hook, effect)
|
|
108
|
+
if (effects[index + 3]) enqueueEffect(fiber, effect)
|
|
109
|
+
}
|
|
110
|
+
hookEffects = undefined
|
|
111
|
+
}
|
|
112
|
+
return rendered
|
|
113
|
+
} finally {
|
|
114
|
+
if (hookEffects) resetHookEffects(hookEffects)
|
|
115
|
+
hookEffects = previousEffects
|
|
116
|
+
hookFlags = previousFlags
|
|
117
|
+
ReactSharedInternals.H = previousDispatcher
|
|
118
|
+
ReactSharedInternals.F = previousFiber
|
|
119
|
+
ReactSharedInternals.I = previousIndex
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function cleanupEffect(hook: Hook, fiber: Fiber): void {
|
|
124
|
+
if (!hook.c) return
|
|
125
|
+
const cleanup = hook.c
|
|
126
|
+
hook.c = null
|
|
127
|
+
if (fiber.cu) {
|
|
128
|
+
const index = fiber.cu.indexOf(cleanup)
|
|
129
|
+
if (index >= 0) fiber.cu.splice(index, 1)
|
|
130
|
+
}
|
|
131
|
+
try { cleanup() } catch (error) { handleCommitError(fiber, error) }
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function useEffectImpl(type: Effect['t'], create: () => any, deps?: ReadonlyArray<unknown>): void {
|
|
135
|
+
const hook = nextHook()
|
|
136
|
+
const fiber = getCurrentFiber()
|
|
137
|
+
const changed = hook.d === undefined || !depsEqual(hook.d, deps)
|
|
138
|
+
if (!changed && !fiber.root?.a && !(type === 1 && fiber.root?.sp)) return
|
|
139
|
+
const previous = hook.d
|
|
140
|
+
hook.d = deps
|
|
141
|
+
const effect: Effect = {
|
|
142
|
+
t: type,
|
|
143
|
+
c: () => {
|
|
144
|
+
cleanupEffect(hook, fiber)
|
|
145
|
+
const cleanup = create()
|
|
146
|
+
// Each effect owns its cleanup even when hooks return the same function.
|
|
147
|
+
hook.c = typeof cleanup === 'function' ? () => {
|
|
148
|
+
if (type === 0) {
|
|
149
|
+
const dispose = () => {
|
|
150
|
+
try { cleanup() } catch (error) { handleCommitError(fiber, error) }
|
|
151
|
+
}
|
|
152
|
+
if (!deferTransitionPassive(dispose)) queueCommitEffects(dispose)
|
|
153
|
+
} else cleanup()
|
|
154
|
+
} : null
|
|
155
|
+
return hook.c
|
|
156
|
+
},
|
|
157
|
+
}
|
|
158
|
+
if (type === 1) effect.d = () => cleanupEffect(hook, fiber)
|
|
159
|
+
;(hookEffects ||= []).push(hook, previous, effect, changed)
|
|
160
|
+
}
|
|
161
|
+
|
|
60
162
|
// Singleton — every method reads render context via ReactSharedInternals,
|
|
61
163
|
// and per-hook closures live on the hook itself, so nothing is render-local
|
|
62
164
|
// to capture. Allocating a fresh wrapper + 17 method closures per function-
|
|
63
165
|
// component render was pure GC pressure.
|
|
64
166
|
const DISPATCHER = makeDispatcherImpl()
|
|
65
167
|
|
|
66
|
-
export function makeDispatcher() {
|
|
67
|
-
return DISPATCHER
|
|
68
|
-
}
|
|
69
|
-
|
|
70
168
|
function makeDispatcherImpl() {
|
|
71
169
|
return {
|
|
72
170
|
useState<S>(initial: S | (() => S)): [S, (a: BasicStateAction<S>) => void] {
|
|
73
|
-
|
|
74
|
-
basicReducer as (state: S, action: BasicStateAction<S>) => S,
|
|
75
|
-
typeof initial == 'function' ? (initial as () => S)() : initial,
|
|
76
|
-
)
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
useReducer<S, A>(reducer: (s: S, a: A) => S, initialArg: any, init?: (a: any) => S) {
|
|
80
|
-
const hook = nextHook()
|
|
81
|
-
const fiber = getCurrentFiber()
|
|
171
|
+
const hook = nextHook(), fiber = getCurrentFiber()
|
|
82
172
|
if (hook.q === undefined) {
|
|
83
|
-
hook.s =
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
173
|
+
hook.s = hook.d = typeof initial === 'function' ? (initial as () => S)() : initial
|
|
174
|
+
hook.c = null
|
|
175
|
+
hook.q = (action: BasicStateAction<S>) => {
|
|
176
|
+
if (fiber.um || fiber.pd) return
|
|
177
|
+
if (ReactSharedInternals.F !== fiber && !hook.c) {
|
|
178
|
+
let next: S
|
|
179
|
+
try {
|
|
180
|
+
next = basicReducer(hook.s, action)
|
|
181
|
+
} catch {
|
|
182
|
+
hook.c = [action]
|
|
183
|
+
scheduleUpdate(fiber)
|
|
184
|
+
return
|
|
185
|
+
}
|
|
186
|
+
if (Object.is(next, hook.s)) return
|
|
89
187
|
hook.s = next
|
|
188
|
+
hook.c = 0
|
|
90
189
|
scheduleUpdate(fiber)
|
|
190
|
+
return
|
|
91
191
|
}
|
|
192
|
+
;(hook.c ||= []).push(action)
|
|
193
|
+
scheduleUpdate(fiber)
|
|
92
194
|
}
|
|
93
|
-
queue.d = dispatch
|
|
94
|
-
hook.q = queue
|
|
95
|
-
} else {
|
|
96
|
-
hook.q.r = reducer
|
|
97
195
|
}
|
|
98
|
-
|
|
196
|
+
reducePending(hook, basicReducer, hook.d)
|
|
197
|
+
hook.d = hook.s
|
|
198
|
+
return [hook.s, hook.q]
|
|
99
199
|
},
|
|
100
200
|
|
|
101
|
-
|
|
201
|
+
useReducer<S, A>(reducer: (s: S, a: A) => S, initialArg: any, init?: (a: any) => S) {
|
|
102
202
|
const hook = nextHook()
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
hook.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
// dispatch/render phase. If render A → B → C all happen back-to-
|
|
112
|
-
// back before the passive microtask drains, dispatch-time cleanup
|
|
113
|
-
// only fires once (between A→B) and fx B + C both run fresh,
|
|
114
|
-
// leaving two side-fx (e.g. two plot SVGs) in the DOM. Doing
|
|
115
|
-
// it here, at effect-run time, means every new create first tears
|
|
116
|
-
// down whatever cleanup is currently live on the hook.
|
|
117
|
-
if (hook.c) {
|
|
118
|
-
try { hook.c() } catch {}
|
|
119
|
-
// The prior cleanup was also pushed onto fiber.cu; remove
|
|
120
|
-
// it so unmount doesn't double-call it.
|
|
121
|
-
if (fiber.cu) {
|
|
122
|
-
const i = fiber.cu.indexOf(hook.c)
|
|
123
|
-
if (i >= 0) fiber.cu.splice(i, 1)
|
|
124
|
-
}
|
|
125
|
-
hook.c = null
|
|
126
|
-
}
|
|
127
|
-
const c = create()
|
|
128
|
-
hook.c = typeof c == 'function' ? c : null
|
|
129
|
-
return hook.c
|
|
130
|
-
},
|
|
131
|
-
}
|
|
132
|
-
enqueueEffect(fiber, effect)
|
|
203
|
+
if (hook.q === undefined) initializeReducer(hook, getCurrentFiber(), initialArg, init)
|
|
204
|
+
reducePending(hook, reducer)
|
|
205
|
+
hook.d = reducer
|
|
206
|
+
return [hook.s, hook.q] as [S, (a: A) => void]
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
useEffect(create: () => any, deps?: ReadonlyArray<unknown>) {
|
|
210
|
+
useEffectImpl(0, create, deps)
|
|
133
211
|
},
|
|
134
212
|
|
|
135
213
|
useLayoutEffect(create: () => any, deps?: ReadonlyArray<unknown>) {
|
|
136
|
-
|
|
137
|
-
const fiber = getCurrentFiber()
|
|
138
|
-
const prevDeps = hook.d
|
|
139
|
-
if (prevDeps !== undefined && depsEqual(prevDeps, deps)) return
|
|
140
|
-
hook.d = deps
|
|
141
|
-
const effect: Effect = {
|
|
142
|
-
t: 1,
|
|
143
|
-
c: () => {
|
|
144
|
-
// Mirror useEffect: tear down the prior cleanup at run time so
|
|
145
|
-
// coalesced renders don't leak side-fx.
|
|
146
|
-
if (hook.c) {
|
|
147
|
-
try { hook.c() } catch {}
|
|
148
|
-
if (fiber.cu) {
|
|
149
|
-
const i = fiber.cu.indexOf(hook.c)
|
|
150
|
-
if (i >= 0) fiber.cu.splice(i, 1)
|
|
151
|
-
}
|
|
152
|
-
hook.c = null
|
|
153
|
-
}
|
|
154
|
-
const c = create()
|
|
155
|
-
hook.c = typeof c == 'function' ? c : null
|
|
156
|
-
return hook.c
|
|
157
|
-
},
|
|
158
|
-
}
|
|
159
|
-
enqueueEffect(fiber, effect)
|
|
214
|
+
useEffectImpl(1, create, deps)
|
|
160
215
|
},
|
|
161
216
|
|
|
162
217
|
useInsertionEffect(create: () => any, deps?: ReadonlyArray<unknown>) {
|
|
163
|
-
|
|
218
|
+
useEffectImpl(2, create, deps)
|
|
164
219
|
},
|
|
165
220
|
|
|
166
221
|
useRef<T>(initial: T) {
|
|
@@ -190,14 +245,16 @@ function makeDispatcherImpl() {
|
|
|
190
245
|
},
|
|
191
246
|
|
|
192
247
|
useImperativeHandle<T>(ref: any, factory: () => T, deps?: ReadonlyArray<unknown>) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
248
|
+
useEffectImpl(1, () => {
|
|
249
|
+
if (!ref) return
|
|
250
|
+
const value = factory()
|
|
251
|
+
if (typeof ref === 'function') {
|
|
252
|
+
const cleanup = ref(value)
|
|
253
|
+
return typeof cleanup === 'function' ? cleanup : () => ref(null)
|
|
254
|
+
}
|
|
255
|
+
ref.current = value
|
|
256
|
+
return () => { ref.current = null }
|
|
257
|
+
}, deps == null ? undefined : [...deps, ref])
|
|
201
258
|
},
|
|
202
259
|
|
|
203
260
|
useDebugValue<T>(_value: T, _formatter?: (v: T) => any): void {
|
|
@@ -217,13 +274,19 @@ function makeDispatcherImpl() {
|
|
|
217
274
|
},
|
|
218
275
|
|
|
219
276
|
useTransition(): [boolean, (fn: () => void) => void] {
|
|
220
|
-
return [false,
|
|
277
|
+
return [false, startTransition]
|
|
221
278
|
},
|
|
222
279
|
|
|
223
280
|
useDeferredValue<T>(v: T): T {
|
|
224
281
|
return v
|
|
225
282
|
},
|
|
226
283
|
|
|
284
|
+
useCacheRefresh(): () => void {
|
|
285
|
+
// There is no client cache to invalidate. Preserve hook identity and
|
|
286
|
+
// leave state and scheduling alone, as with the uncached client cache().
|
|
287
|
+
return this.useCallback(() => {}, [])
|
|
288
|
+
},
|
|
289
|
+
|
|
227
290
|
useSyncExternalStore<T>(
|
|
228
291
|
subscribe: (cb: () => void) => () => void,
|
|
229
292
|
getSnapshot: () => T,
|
|
@@ -251,26 +314,19 @@ function makeDispatcherImpl() {
|
|
|
251
314
|
const isHydrating = Boolean(root?.h)
|
|
252
315
|
const value =
|
|
253
316
|
isHydrating && getServerSnapshot ? getServerSnapshot() : getSnapshot()
|
|
317
|
+
if (!Object.is(hook.s, value)) hookFlags |= 1
|
|
254
318
|
hook.s = value
|
|
255
319
|
|
|
256
320
|
const deps = [subscribe]
|
|
257
|
-
|
|
321
|
+
const changed = hook.d === undefined || !depsEqual(hook.d, deps)
|
|
322
|
+
if (changed || fiber.root?.a) {
|
|
323
|
+
const previous = hook.d
|
|
258
324
|
hook.d = deps
|
|
259
325
|
const effect: Effect = {
|
|
260
326
|
t: 1,
|
|
327
|
+
s: true,
|
|
261
328
|
c: () => {
|
|
262
|
-
|
|
263
|
-
try {
|
|
264
|
-
hook.c()
|
|
265
|
-
} catch {
|
|
266
|
-
// ignore cleanup failures
|
|
267
|
-
}
|
|
268
|
-
if (fiber.cu) {
|
|
269
|
-
const i = fiber.cu.indexOf(hook.c)
|
|
270
|
-
if (i >= 0) fiber.cu.splice(i, 1)
|
|
271
|
-
}
|
|
272
|
-
hook.c = null
|
|
273
|
-
}
|
|
329
|
+
cleanupEffect(hook, fiber)
|
|
274
330
|
|
|
275
331
|
let unsubscribed = false
|
|
276
332
|
const cleanup = () => {
|
|
@@ -293,7 +349,6 @@ function makeDispatcherImpl() {
|
|
|
293
349
|
}
|
|
294
350
|
|
|
295
351
|
if (!Object.is(hook.s, next)) {
|
|
296
|
-
hook.s = next
|
|
297
352
|
scheduleUpdate(fiber)
|
|
298
353
|
}
|
|
299
354
|
}
|
|
@@ -311,12 +366,13 @@ function makeDispatcherImpl() {
|
|
|
311
366
|
return cleanup
|
|
312
367
|
},
|
|
313
368
|
}
|
|
314
|
-
|
|
369
|
+
;(hookEffects ||= []).push(hook, previous, effect, changed)
|
|
315
370
|
}
|
|
316
371
|
return value
|
|
317
372
|
},
|
|
318
373
|
|
|
319
374
|
use<T>(resource: any): T {
|
|
375
|
+
if (resource?.$$typeof === REACT_RECOVERABLE_TYPE) return undefined as T
|
|
320
376
|
if (resource == null) {
|
|
321
377
|
if (process.env.NODE_ENV !== 'production') {
|
|
322
378
|
throw new Error('use() received null or undefined')
|
|
@@ -372,7 +428,7 @@ let idCounter = 0
|
|
|
372
428
|
function findRootFromFiber(fiber: Fiber): FiberRoot | null {
|
|
373
429
|
let f: Fiber | null = fiber
|
|
374
430
|
while (f) {
|
|
375
|
-
if (f.root) return f.root
|
|
431
|
+
if (f.root) return fiber.root = f.root
|
|
376
432
|
f = f.parent
|
|
377
433
|
}
|
|
378
434
|
return null
|
package/src/dom/dom.ts
CHANGED
|
@@ -9,6 +9,7 @@ const BOOLEAN_ATTRS = new Set([
|
|
|
9
9
|
'autoplay',
|
|
10
10
|
'checked',
|
|
11
11
|
'controls',
|
|
12
|
+
'credentialless',
|
|
12
13
|
'default',
|
|
13
14
|
'defer',
|
|
14
15
|
'disabled',
|
|
@@ -51,6 +52,54 @@ export function isSvgElement(el: Element): boolean {
|
|
|
51
52
|
return (el as any).ownerSVGElement !== undefined || el.tagName === 'svg'
|
|
52
53
|
}
|
|
53
54
|
|
|
55
|
+
export function syncInputValue(el: HTMLInputElement, props: any, prev?: any): void {
|
|
56
|
+
if (!prev) {
|
|
57
|
+
el.checked = el.defaultChecked = !!(props.checked ?? props.defaultChecked)
|
|
58
|
+
} else if (props.checked != null) {
|
|
59
|
+
el.checked = !!props.checked
|
|
60
|
+
} else if (props.defaultChecked != null) {
|
|
61
|
+
el.defaultChecked = !!props.defaultChecked
|
|
62
|
+
}
|
|
63
|
+
const value = props.value
|
|
64
|
+
const fallback = props.defaultValue
|
|
65
|
+
if (!prev) {
|
|
66
|
+
if (value == null && (el.type === 'submit' || el.type === 'reset')) return
|
|
67
|
+
if (value != null || fallback != null) {
|
|
68
|
+
const initial = '' + (value ?? fallback)
|
|
69
|
+
if (el.value !== initial) el.value = initial
|
|
70
|
+
el.defaultValue = initial
|
|
71
|
+
}
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
if (value != null) {
|
|
75
|
+
// Number inputs keep equivalent user spelling, including trailing zeroes.
|
|
76
|
+
if (el.type === 'number' ? (value === 0 && el.value === '') || el.value != value : el.value !== '' + value) {
|
|
77
|
+
el.value = '' + value
|
|
78
|
+
}
|
|
79
|
+
const nextDefault = el.type === 'number' && el.value == value ? el.value : '' + value
|
|
80
|
+
if (el.defaultValue !== nextDefault) el.defaultValue = nextDefault
|
|
81
|
+
} else if (fallback != null) {
|
|
82
|
+
if (el.defaultValue !== '' + fallback) el.defaultValue = '' + fallback
|
|
83
|
+
} else if (prev.defaultValue != null || el.type === 'submit' || el.type === 'reset') {
|
|
84
|
+
el.removeAttribute('value')
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function syncTextareaValue(el: HTMLTextAreaElement, props: any, mounting = false): void {
|
|
89
|
+
if (mounting) {
|
|
90
|
+
const children = props.children
|
|
91
|
+
const initial = props.value ?? props.defaultValue ?? (Array.isArray(children) ? children[0] : children) ?? ''
|
|
92
|
+
el.defaultValue = initial
|
|
93
|
+
// The strict check also preserves React's clean numeric-default state.
|
|
94
|
+
if (initial !== '' && el.textContent === initial) el.value = initial
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
const value = props.value
|
|
98
|
+
if (value != null && el.value !== '' + value) el.value = '' + value
|
|
99
|
+
const fallback = props.defaultValue ?? value ?? ''
|
|
100
|
+
if (el.defaultValue !== '' + fallback) el.defaultValue = '' + fallback
|
|
101
|
+
}
|
|
102
|
+
|
|
54
103
|
export function setProp(
|
|
55
104
|
el: Element,
|
|
56
105
|
name: string,
|
|
@@ -59,6 +108,14 @@ export function setProp(
|
|
|
59
108
|
isSvg: boolean,
|
|
60
109
|
): void {
|
|
61
110
|
if (name === 'children' || name === 'key' || name === 'ref') return
|
|
111
|
+
// These names need no alias or boolean-attribute normalization.
|
|
112
|
+
if (name.length > 5 && (name.charCodeAt(0) === 97 || name.charCodeAt(0) === 100)) {
|
|
113
|
+
if (name.startsWith('aria-') || name.startsWith('data-')) {
|
|
114
|
+
if (next == null) el.removeAttribute(name)
|
|
115
|
+
else el.setAttribute(name, '' + next)
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
}
|
|
62
119
|
const attr = attributeName(name, isSvg)
|
|
63
120
|
|
|
64
121
|
// defaultValue / defaultChecked are IDL-property-only — they seed the
|
|
@@ -76,19 +133,8 @@ export function setProp(
|
|
|
76
133
|
return
|
|
77
134
|
}
|
|
78
135
|
|
|
79
|
-
if (name === 'className') {
|
|
80
|
-
|
|
81
|
-
if (next == null) el.removeAttribute('class')
|
|
82
|
-
else el.setAttribute('class', '' + next)
|
|
83
|
-
} else {
|
|
84
|
-
;(el as HTMLElement).className = next == null ? '' : '' + next
|
|
85
|
-
}
|
|
86
|
-
return
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (name === 'class') {
|
|
90
|
-
if (next == null) el.removeAttribute('class')
|
|
91
|
-
else el.setAttribute('class', '' + next)
|
|
136
|
+
if (name === 'className' && !isSvg) {
|
|
137
|
+
;(el as HTMLElement).className = next == null ? '' : '' + next
|
|
92
138
|
return
|
|
93
139
|
}
|
|
94
140
|
|
|
@@ -105,17 +151,11 @@ export function setProp(
|
|
|
105
151
|
}
|
|
106
152
|
|
|
107
153
|
if (name[0] === 'o' && name[1] === 'n') {
|
|
108
|
-
setEventHandler(el, name, next
|
|
154
|
+
setEventHandler(el, name, next)
|
|
109
155
|
return
|
|
110
156
|
}
|
|
111
157
|
|
|
112
|
-
if (name === 'htmlFor') {
|
|
113
|
-
if (next == null) el.removeAttribute('for')
|
|
114
|
-
else el.setAttribute('for', '' + next)
|
|
115
|
-
return
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (STRING_BOOLEAN_ATTRS.has(attr)) {
|
|
158
|
+
if (name === 'className' || name === 'class' || name === 'htmlFor' || STRING_BOOLEAN_ATTRS.has(attr)) {
|
|
119
159
|
if (next == null) el.removeAttribute(attr)
|
|
120
160
|
else el.setAttribute(attr, '' + next)
|
|
121
161
|
return
|
|
@@ -128,32 +168,12 @@ export function setProp(
|
|
|
128
168
|
} catch {}
|
|
129
169
|
}
|
|
130
170
|
|
|
131
|
-
if (BOOLEAN_ATTRS.has(
|
|
132
|
-
if (next) el.setAttribute(attr, '')
|
|
133
|
-
else el.removeAttribute(attr)
|
|
134
|
-
return
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// aria-* and data-* attributes stringify booleans to `"true"`/`"false"`
|
|
138
|
-
// rather than using the HTML boolean-attribute presence/absence semantics.
|
|
139
|
-
// This matches React and the ARIA spec (aria-hidden="false" is meaningful).
|
|
140
|
-
if (name.length > 5 && (name.charCodeAt(0) === 97 /* a */ || name.charCodeAt(0) === 100 /* d */)) {
|
|
141
|
-
if (name.startsWith('aria-') || name.startsWith('data-')) {
|
|
142
|
-
if (next == null) {
|
|
143
|
-
el.removeAttribute(attr)
|
|
144
|
-
} else {
|
|
145
|
-
el.setAttribute(attr, '' + next)
|
|
146
|
-
}
|
|
147
|
-
return
|
|
148
|
-
}
|
|
149
|
-
}
|
|
171
|
+
if (BOOLEAN_ATTRS.has(attr)) next = !!next
|
|
150
172
|
|
|
151
173
|
if (next == null || next === false) {
|
|
152
174
|
el.removeAttribute(attr)
|
|
153
|
-
} else if (next === true) {
|
|
154
|
-
el.setAttribute(attr, '')
|
|
155
175
|
} else {
|
|
156
|
-
el.setAttribute(attr, ''
|
|
176
|
+
el.setAttribute(attr, next === true ? '' : next)
|
|
157
177
|
}
|
|
158
178
|
}
|
|
159
179
|
|
|
@@ -241,7 +261,7 @@ export interface SyntheticEvent extends Event {
|
|
|
241
261
|
currentTarget: EventTarget & Element
|
|
242
262
|
}
|
|
243
263
|
|
|
244
|
-
function setEventHandler(el: Element, name: string, next: any
|
|
264
|
+
function setEventHandler(el: Element, name: string, next: any): void {
|
|
245
265
|
// Only function handlers are accepted. Reject strings/objects/etc — the
|
|
246
266
|
// legacy `onclick="..."` HTML attribute (string handler) is a known XSS
|
|
247
267
|
// vector if a parent spreads untrusted props onto a host element. React
|
|
@@ -256,13 +276,11 @@ function setEventHandler(el: Element, name: string, next: any, prev: any): void
|
|
|
256
276
|
// `onInput` on the same text input — which both dispatch from the native
|
|
257
277
|
// `input` event — can coexist without clobbering each other's handlers.
|
|
258
278
|
const handlers = ((el as any).__handlers ||= Object.create(null))
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
const existing = handlers[key]
|
|
279
|
+
const existing = handlers[name]
|
|
262
280
|
|
|
263
281
|
if (existing && !next) {
|
|
264
|
-
el.removeEventListener(existing.event, existing.listener,
|
|
265
|
-
handlers[
|
|
282
|
+
el.removeEventListener(existing.event, existing.listener, capture)
|
|
283
|
+
handlers[name] = null
|
|
266
284
|
return
|
|
267
285
|
}
|
|
268
286
|
|
|
@@ -271,7 +289,6 @@ function setEventHandler(el: Element, name: string, next: any, prev: any): void
|
|
|
271
289
|
current: next as Function,
|
|
272
290
|
listener: null as any,
|
|
273
291
|
event: eventName,
|
|
274
|
-
capture,
|
|
275
292
|
}
|
|
276
293
|
entry.listener = (e: Event) => {
|
|
277
294
|
// React hands handlers a SyntheticEvent that carries `.nativeEvent`.
|
|
@@ -282,7 +299,7 @@ function setEventHandler(el: Element, name: string, next: any, prev: any): void
|
|
|
282
299
|
if ((e as any).nativeEvent === undefined) (e as any).nativeEvent = e
|
|
283
300
|
entry.current(e)
|
|
284
301
|
}
|
|
285
|
-
handlers[
|
|
302
|
+
handlers[name] = entry
|
|
286
303
|
el.addEventListener(eventName, entry.listener, capture)
|
|
287
304
|
return
|
|
288
305
|
}
|
|
@@ -291,10 +308,9 @@ function setEventHandler(el: Element, name: string, next: any, prev: any): void
|
|
|
291
308
|
// Re-bind if the effective DOM event changed (e.g. <input> whose `type`
|
|
292
309
|
// flipped from "text" to "checkbox" — onChange should now follow `change`
|
|
293
310
|
// instead of `input`). This is rare but keeps semantics correct.
|
|
294
|
-
if (existing.event !== eventName
|
|
295
|
-
el.removeEventListener(existing.event, existing.listener,
|
|
311
|
+
if (existing.event !== eventName) {
|
|
312
|
+
el.removeEventListener(existing.event, existing.listener, capture)
|
|
296
313
|
existing.event = eventName
|
|
297
|
-
existing.capture = capture
|
|
298
314
|
el.addEventListener(eventName, existing.listener, capture)
|
|
299
315
|
}
|
|
300
316
|
existing.current = next
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FiberTag, type Fiber } from '../core'
|
|
2
|
+
|
|
3
|
+
export function componentStack(fiber: Fiber | null): string {
|
|
4
|
+
let stack = ''
|
|
5
|
+
for (; fiber; fiber = fiber.parent) {
|
|
6
|
+
let type = fiber.type
|
|
7
|
+
while (type && typeof type === 'object') type = type.type || type.render
|
|
8
|
+
const name = typeof type === 'string' ? type
|
|
9
|
+
: typeof type === 'function' ? type.displayName || type.name || 'Anonymous'
|
|
10
|
+
: fiber.tag === FiberTag.Suspense ? 'Suspense'
|
|
11
|
+
: fiber.tag === FiberTag.Activity ? 'Activity' : ''
|
|
12
|
+
if (name) stack += '\n at ' + name
|
|
13
|
+
}
|
|
14
|
+
return stack
|
|
15
|
+
}
|