@tanstack/redact 0.0.21 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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 +72 -15
- 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 +17 -8
- 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 +7 -2
- package/dist/react/context.js +3 -11
- package/dist/react/context.js.map +3 -3
- package/dist/react/element.d.ts +6 -3
- package/dist/react/element.js +7 -11
- 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 +150 -110
- 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 +70 -13
- package/src/dom/features/context/stub.ts +10 -5
- 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/context.ts +4 -11
- package/src/react/element.ts +11 -12
- 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 +79 -26
- package/src/vite/index.ts +30 -13
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import type { FiberRoot } from '../../../core'
|
|
2
|
+
import { ReactSharedInternals } from '../../../react/shared-internals'
|
|
3
|
+
import { currentCommit, prepareCommit, commitBeforeMutation, commitMutation, commitSynchronously, type CommitPlan } from '../../commit'
|
|
4
|
+
import { prepareViewTransition } from './visual'
|
|
5
|
+
import { recoverRootError } from '../../reconcile'
|
|
6
|
+
|
|
7
|
+
type Work = { commit: () => void; scopes: Set<Set<string>> }
|
|
8
|
+
type Visual = NonNullable<ReturnType<typeof prepareViewTransition>>
|
|
9
|
+
interface Transaction {
|
|
10
|
+
native?: ViewTransition
|
|
11
|
+
visual: Visual
|
|
12
|
+
work: Map<FiberRoot, Work>
|
|
13
|
+
layout: Array<() => void>
|
|
14
|
+
passive: Array<() => void>
|
|
15
|
+
consumed: boolean
|
|
16
|
+
cancelled: boolean
|
|
17
|
+
ready: boolean
|
|
18
|
+
plans: CommitPlan[]
|
|
19
|
+
preparing: boolean
|
|
20
|
+
}
|
|
21
|
+
interface Coordinator {
|
|
22
|
+
queued: Map<FiberRoot, Work>
|
|
23
|
+
active?: Transaction | undefined
|
|
24
|
+
flush: () => void
|
|
25
|
+
scheduled: boolean
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const marks = new Map<FiberRoot, Set<Set<string>> | null>()
|
|
29
|
+
const documents = new Map<Document, Coordinator>()
|
|
30
|
+
let committing: Transaction | undefined
|
|
31
|
+
|
|
32
|
+
function ownerDocument(root: FiberRoot): Document {
|
|
33
|
+
return root.c.nodeType === 9 ? root.c as unknown as Document : root.c.ownerDocument!
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function drain(queue: Array<() => void>): void {
|
|
37
|
+
while (queue.length) queue.shift()!()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function passive(transaction: Transaction): void {
|
|
41
|
+
if (transaction.consumed) transaction.visual.restore()
|
|
42
|
+
drain(transaction.passive)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function release(doc: Document, coordinator: Coordinator): void {
|
|
46
|
+
if (!coordinator.active && !coordinator.queued.size && documents.get(doc) === coordinator) documents.delete(doc)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function render(work: Map<FiberRoot, Work>): void {
|
|
50
|
+
for (const entry of work.values()) entry.commit()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function prepareRoot(transaction: Transaction, root: FiberRoot, commit: () => void): void {
|
|
54
|
+
try {
|
|
55
|
+
prepareCommit(() => {
|
|
56
|
+
transaction.plans.push(currentCommit!)
|
|
57
|
+
commit()
|
|
58
|
+
})
|
|
59
|
+
} catch (error) {
|
|
60
|
+
transaction.plans.pop()
|
|
61
|
+
if (!recoverRootError(error)) throw error
|
|
62
|
+
transaction.work.delete(root)
|
|
63
|
+
transaction.visual.exclude(root)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function beforeMutation(transaction: Transaction): void {
|
|
68
|
+
for (const plan of transaction.plans) commitBeforeMutation(plan)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function mutation(transaction: Transaction): void {
|
|
72
|
+
for (const plan of transaction.plans) commitMutation(plan)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function markTransitionUpdate(root: FiberRoot): void {
|
|
76
|
+
if (committing) return
|
|
77
|
+
const coordinator = documents.size ? documents.get(ownerDocument(root)) : undefined
|
|
78
|
+
if (coordinator?.active) passive(coordinator.active)
|
|
79
|
+
const scope = ReactSharedInternals.T
|
|
80
|
+
if (scope) {
|
|
81
|
+
if (marks.get(root) !== null) {
|
|
82
|
+
let scopes = marks.get(root)
|
|
83
|
+
if (!scopes) marks.set(root, scopes = new Set())
|
|
84
|
+
scopes.add(scope)
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
if (marks.has(root)) marks.set(root, null)
|
|
88
|
+
if (coordinator) cancel(coordinator)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function deferTransition(root: FiberRoot, commit: () => void, flush: () => void): boolean {
|
|
93
|
+
if (committing?.preparing && !currentCommit && ownerDocument(root) === committing.visual.document) {
|
|
94
|
+
prepareRoot(committing, root, commit)
|
|
95
|
+
return true
|
|
96
|
+
}
|
|
97
|
+
if (!marks.size && !documents.size) return false
|
|
98
|
+
const scopes = marks.get(root)
|
|
99
|
+
marks.delete(root)
|
|
100
|
+
const doc = ownerDocument(root)
|
|
101
|
+
const activeCoordinator = documents.get(doc)
|
|
102
|
+
if (activeCoordinator?.active?.plans.length && !activeCoordinator.active.consumed && !currentCommit) {
|
|
103
|
+
// A reentrant urgent render must consume the already-rendered commit
|
|
104
|
+
// before reconciling another tree against it.
|
|
105
|
+
if (committing || !scopes) cancel(activeCoordinator)
|
|
106
|
+
}
|
|
107
|
+
if (committing || !scopes || !doc.startViewTransition) return false
|
|
108
|
+
let coordinator = documents.get(doc)
|
|
109
|
+
if (!coordinator) {
|
|
110
|
+
coordinator = { queued: new Map(), flush, scheduled: false }
|
|
111
|
+
documents.set(doc, coordinator)
|
|
112
|
+
}
|
|
113
|
+
const existing = coordinator.queued.get(root)
|
|
114
|
+
if (existing) for (const scope of scopes) existing.scopes.add(scope)
|
|
115
|
+
else coordinator.queued.set(root, { commit, scopes })
|
|
116
|
+
kick(doc, coordinator)
|
|
117
|
+
return true
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function kick(doc: Document, coordinator: Coordinator): void {
|
|
121
|
+
if (coordinator.active || coordinator.scheduled || !coordinator.queued.size) return
|
|
122
|
+
coordinator.scheduled = true
|
|
123
|
+
queueMicrotask(async () => {
|
|
124
|
+
coordinator.scheduled = false
|
|
125
|
+
if (coordinator.active || !coordinator.queued.size) return
|
|
126
|
+
const work = coordinator.queued
|
|
127
|
+
coordinator.queued = new Map()
|
|
128
|
+
const types = new Set<string>()
|
|
129
|
+
for (const entry of work.values()) for (const scope of entry.scopes) for (const type of scope) types.add(type)
|
|
130
|
+
const visual = prepareViewTransition(work.keys(), [...types])
|
|
131
|
+
if (!visual) {
|
|
132
|
+
commitSynchronously(() => render(work))
|
|
133
|
+
release(doc, coordinator)
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
const transaction: Transaction = { visual, work, layout: [], passive: [], plans: [], preparing: true, consumed: false, cancelled: false, ready: false }
|
|
137
|
+
coordinator.active = transaction
|
|
138
|
+
try {
|
|
139
|
+
try {
|
|
140
|
+
within(transaction, () => {
|
|
141
|
+
for (const [root, entry] of work) prepareRoot(transaction, root, entry.commit)
|
|
142
|
+
coordinator.flush()
|
|
143
|
+
})
|
|
144
|
+
} finally { transaction.preparing = false }
|
|
145
|
+
const resources = visual.prepare()
|
|
146
|
+
if (resources) await resources
|
|
147
|
+
if (transaction.cancelled) return
|
|
148
|
+
within(transaction, () => beforeMutation(transaction))
|
|
149
|
+
if (!visual.beforeCommit()) {
|
|
150
|
+
cancel(coordinator)
|
|
151
|
+
return
|
|
152
|
+
}
|
|
153
|
+
} catch (error) {
|
|
154
|
+
cancel(coordinator)
|
|
155
|
+
report(transaction, error)
|
|
156
|
+
return
|
|
157
|
+
}
|
|
158
|
+
const update = () => {
|
|
159
|
+
if (transaction.consumed) return
|
|
160
|
+
transaction.consumed = true
|
|
161
|
+
const navigation = (doc.defaultView as any)?.navigation?.transition
|
|
162
|
+
const fonts = doc.fonts
|
|
163
|
+
const wasLoaded = fonts?.status === 'loaded'
|
|
164
|
+
within(transaction, () => {
|
|
165
|
+
mutation(transaction)
|
|
166
|
+
coordinator.flush()
|
|
167
|
+
})
|
|
168
|
+
const finishCommit = () => {
|
|
169
|
+
if (transaction.cancelled) return
|
|
170
|
+
within(transaction, () => { drain(transaction.layout); coordinator.flush() })
|
|
171
|
+
if (navigation) return navigation.finished.catch(() => {}).then(() => {
|
|
172
|
+
if (!transaction.cancelled) visual.afterCommit()
|
|
173
|
+
})
|
|
174
|
+
visual.afterCommit()
|
|
175
|
+
}
|
|
176
|
+
const resources = visual.waitForResources(!!wasLoaded)
|
|
177
|
+
if (resources) return resources.then(finishCommit)
|
|
178
|
+
return finishCommit()
|
|
179
|
+
}
|
|
180
|
+
try {
|
|
181
|
+
const native = transaction.native = doc.startViewTransition({ update, types: [...types] })
|
|
182
|
+
native.updateCallbackDone.catch(error => report(transaction, error))
|
|
183
|
+
native.ready.then(() => {
|
|
184
|
+
if (!transaction.cancelled) {
|
|
185
|
+
transaction.ready = true
|
|
186
|
+
try { visual.ready() } catch (error) { report(transaction, error) }
|
|
187
|
+
}
|
|
188
|
+
}, error => {
|
|
189
|
+
try {
|
|
190
|
+
if (!transaction.cancelled && reportable(error)) {
|
|
191
|
+
const root = transaction.work.keys().next().value
|
|
192
|
+
if (root?.re) root.re(error, { componentStack: null })
|
|
193
|
+
else if (typeof reportError === 'function') reportError(error)
|
|
194
|
+
else queueMicrotask(() => { throw error })
|
|
195
|
+
}
|
|
196
|
+
} finally {
|
|
197
|
+
transaction.cancelled = true
|
|
198
|
+
try { visual.cancel() } finally { consume(transaction) }
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
native.finished.then(() => finish(doc, coordinator, transaction), () => finish(doc, coordinator, transaction))
|
|
202
|
+
} catch {
|
|
203
|
+
cancel(coordinator)
|
|
204
|
+
}
|
|
205
|
+
})
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function reportable(error: unknown): boolean {
|
|
209
|
+
return error !== null && !(error && typeof error === 'object' && 'name' in error && error.name === 'InvalidStateError' &&
|
|
210
|
+
'message' in error && (
|
|
211
|
+
error.message === 'View transition was skipped because document visibility state is hidden.' ||
|
|
212
|
+
error.message === 'Skipping view transition because document visibility state has become hidden.' ||
|
|
213
|
+
error.message === 'Skipping view transition because viewport size changed.' ||
|
|
214
|
+
error.message === 'Transition was aborted because of invalid state'
|
|
215
|
+
))
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function consume(transaction: Transaction): void {
|
|
219
|
+
transaction.consumed = true
|
|
220
|
+
within(transaction, () => {
|
|
221
|
+
beforeMutation(transaction)
|
|
222
|
+
mutation(transaction)
|
|
223
|
+
})
|
|
224
|
+
drain(transaction.layout)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function within(transaction: Transaction, work: () => void): void {
|
|
228
|
+
const previous = committing
|
|
229
|
+
committing = transaction
|
|
230
|
+
try { work() } finally { committing = previous }
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function report(transaction: Transaction, error: unknown): void {
|
|
234
|
+
const root = transaction.work.keys().next().value
|
|
235
|
+
if (root?.ue) root.ue(error, { componentStack: null })
|
|
236
|
+
else queueMicrotask(() => { throw error })
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function finish(doc: Document, coordinator: Coordinator, transaction: Transaction): void {
|
|
240
|
+
if (coordinator.active === transaction) coordinator.active = undefined
|
|
241
|
+
try { passive(transaction) } catch (error) { report(transaction, error) } finally {
|
|
242
|
+
try { transaction.visual.finish() } catch (error) { report(transaction, error) } finally {
|
|
243
|
+
if (coordinator.queued.size) kick(doc, coordinator)
|
|
244
|
+
else release(doc, coordinator)
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function cancel(coordinator: Coordinator): void {
|
|
250
|
+
const transaction = coordinator.active
|
|
251
|
+
const queued = coordinator.queued
|
|
252
|
+
const root = queued.keys().next().value
|
|
253
|
+
const doc = transaction?.visual.document ?? (root ? ownerDocument(root) : undefined)
|
|
254
|
+
coordinator.queued = new Map()
|
|
255
|
+
if (transaction) {
|
|
256
|
+
if (!transaction.ready) {
|
|
257
|
+
coordinator.active = undefined
|
|
258
|
+
transaction.cancelled = true
|
|
259
|
+
transaction.native?.skipTransition()
|
|
260
|
+
try { transaction.visual.cancel() } catch (error) { report(transaction, error) }
|
|
261
|
+
}
|
|
262
|
+
consume(transaction)
|
|
263
|
+
passive(transaction)
|
|
264
|
+
}
|
|
265
|
+
commitSynchronously(() => render(queued))
|
|
266
|
+
if (doc) release(doc, coordinator)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export function cancelTransitions(): void {
|
|
270
|
+
if (!marks.size && !documents.size) return
|
|
271
|
+
marks.clear()
|
|
272
|
+
for (const [doc, coordinator] of [...documents]) {
|
|
273
|
+
cancel(coordinator)
|
|
274
|
+
release(doc, coordinator)
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export function deferTransitionLayout(work: () => void): boolean {
|
|
279
|
+
if (!committing) return false
|
|
280
|
+
committing.layout.push(work)
|
|
281
|
+
return true
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export function deferTransitionPassive(work: () => void): boolean {
|
|
285
|
+
if (!committing) return false
|
|
286
|
+
committing.passive.push(work)
|
|
287
|
+
return true
|
|
288
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './full'
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
export type TransitionImages = Map<HTMLImageElement, { src?: unknown; srcSet?: unknown; onLoad?: unknown; loading?: unknown }>
|
|
2
|
+
|
|
3
|
+
let imageBudget = 0
|
|
4
|
+
|
|
5
|
+
function imageBytes(image: HTMLImageElement): number {
|
|
6
|
+
return (image.width || 100) * (image.height || 100) * (image.ownerDocument.defaultView?.devicePixelRatio || 1) * 0.25
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function staticResource(type: string): boolean {
|
|
10
|
+
return /^(css|script|font|img|image|input|link)$/.test(type)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Match React's estimate from up to eleven groups of overlapping transfers,
|
|
14
|
+
// falling back to the browser's downlink estimate and then 5 Mbps.
|
|
15
|
+
function bandwidth(doc: Document): number {
|
|
16
|
+
const view = doc.defaultView!
|
|
17
|
+
const entries = view.performance.getEntriesByType?.('resource') as PerformanceResourceTiming[] | undefined
|
|
18
|
+
let count = 0, bits = 0
|
|
19
|
+
for (let i = 0; entries && i < entries.length; i++) {
|
|
20
|
+
const entry = entries[i]!
|
|
21
|
+
if (!entry.transferSize || !entry.duration || !staticResource(entry.initiatorType)) continue
|
|
22
|
+
let overlap = 0
|
|
23
|
+
for (++i; i < entries.length; i++) {
|
|
24
|
+
const next = entries[i]!
|
|
25
|
+
if (next.startTime > entry.responseEnd) break
|
|
26
|
+
if (next.transferSize && staticResource(next.initiatorType)) {
|
|
27
|
+
overlap += next.transferSize * (next.responseEnd < entry.responseEnd ? 1 :
|
|
28
|
+
(entry.responseEnd - next.startTime) / (next.responseEnd - next.startTime))
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
i--
|
|
32
|
+
bits += 8 * (entry.transferSize + overlap) / (entry.duration / 1000)
|
|
33
|
+
if (++count > 10) break
|
|
34
|
+
}
|
|
35
|
+
if (count) return bits / count / 1000000
|
|
36
|
+
const downlink = (view.navigator as any).connection?.downlink
|
|
37
|
+
return typeof downlink === 'number' ? downlink : 5
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function transitionResources(doc: Document, previous: TransitionImages, next: TransitionImages) {
|
|
41
|
+
const pending: HTMLImageElement[] = []
|
|
42
|
+
const releases = new Set<() => void>()
|
|
43
|
+
|
|
44
|
+
function wait(promises: Promise<unknown>[], timeout: number, cleanups: Array<() => void> = []): Promise<void> | undefined {
|
|
45
|
+
if (!promises.length) return
|
|
46
|
+
return new Promise(resolve => {
|
|
47
|
+
const finish = () => {
|
|
48
|
+
if (!releases.delete(finish)) return
|
|
49
|
+
clearTimeout(timer)
|
|
50
|
+
for (const cleanup of cleanups) cleanup()
|
|
51
|
+
resolve()
|
|
52
|
+
}
|
|
53
|
+
const timer = setTimeout(finish, timeout)
|
|
54
|
+
releases.add(finish)
|
|
55
|
+
Promise.all(promises).then(finish, finish)
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
before() {
|
|
61
|
+
const promises: Promise<unknown>[] = []
|
|
62
|
+
let bytes = 0
|
|
63
|
+
for (const [image, props] of next) {
|
|
64
|
+
const old = previous.get(image)
|
|
65
|
+
if (props.src == null || props.src === '' || props.onLoad != null || props.loading === 'lazy' ||
|
|
66
|
+
(old && props.src === old.src && props.srcSet === old.srcSet) || typeof image.decode !== 'function') continue
|
|
67
|
+
if (!image.complete) { pending.push(image); bytes += imageBytes(image) }
|
|
68
|
+
promises.push(image.decode().catch(() => {}))
|
|
69
|
+
}
|
|
70
|
+
if (bytes && !imageBudget) imageBudget = 125 * bandwidth(doc) * 500
|
|
71
|
+
return wait(promises, bytes > imageBudget ? 50 : 800)
|
|
72
|
+
},
|
|
73
|
+
after(fontsWereLoaded: boolean) {
|
|
74
|
+
const promises: Promise<unknown>[] = []
|
|
75
|
+
const cleanups: Array<() => void> = []
|
|
76
|
+
if (fontsWereLoaded) {
|
|
77
|
+
// Discover fonts introduced by mutation before the browser captures.
|
|
78
|
+
doc.documentElement.getBoundingClientRect()
|
|
79
|
+
if (doc.fonts.status === 'loading') promises.push(doc.fonts.ready)
|
|
80
|
+
}
|
|
81
|
+
const images: HTMLImageElement[] = []
|
|
82
|
+
let bytes = 0
|
|
83
|
+
const view = doc.defaultView!
|
|
84
|
+
for (const image of pending) {
|
|
85
|
+
if (image.complete) continue
|
|
86
|
+
const rect = image.getBoundingClientRect()
|
|
87
|
+
if (rect.bottom <= 0 || rect.right <= 0 || rect.top >= view.innerHeight || rect.left >= view.innerWidth) continue
|
|
88
|
+
bytes += imageBytes(image)
|
|
89
|
+
if (bytes > imageBudget) { images.length = 0; break }
|
|
90
|
+
images.push(image)
|
|
91
|
+
}
|
|
92
|
+
for (const image of images) {
|
|
93
|
+
promises.push(new Promise<void>(resolve => {
|
|
94
|
+
const loaded = () => resolve()
|
|
95
|
+
image.addEventListener('load', loaded)
|
|
96
|
+
image.addEventListener('error', loaded)
|
|
97
|
+
cleanups.push(() => {
|
|
98
|
+
image.removeEventListener('load', loaded)
|
|
99
|
+
image.removeEventListener('error', loaded)
|
|
100
|
+
})
|
|
101
|
+
}))
|
|
102
|
+
}
|
|
103
|
+
return wait(promises, 500, cleanups)
|
|
104
|
+
},
|
|
105
|
+
cancel() { for (const release of releases) release() },
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FiberRoot } from '../../../core'
|
|
2
|
+
|
|
3
|
+
export function markTransitionUpdate(_root: FiberRoot): void {}
|
|
4
|
+
export function deferTransition(_root: FiberRoot, _commit: () => void, _flush: () => void): boolean { return false }
|
|
5
|
+
export function cancelTransitions(): void {}
|
|
6
|
+
export function deferTransitionLayout(_work: () => void): boolean { return false }
|
|
7
|
+
export function deferTransitionPassive(_work: () => void): boolean { return false }
|