@bgub/fig-reconciler 0.1.0-alpha.0 → 0.1.0-alpha.2

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/index.js CHANGED
@@ -1,27 +1,8 @@
1
- import { devtoolsTypeName } from "./devtools.js";
2
- import { Fragment } from "@bgub/fig";
3
- import { collectChildren, dataResourceKeysForError, invalidChildError, isActivity, isAssets, isContext, isErrorBoundary, isPortal, isSuspense, isThenable, isValidElement, isViewTransition, readThenable, setCurrentDataStore, setCurrentDispatcher, setTransitionHandler } from "@bgub/fig/internal";
4
- //#region src/fiber-work.ts
5
- const StoreConsistencyFlag = 2048;
6
- const ContextPropagationFlag = 1024;
7
- const NotHoistedFlag = 8192;
8
- const ViewTransitionStaticFlag = 4096;
9
- const StaticFlagsMask = ViewTransitionStaticFlag;
10
- function childSubtreeFlags(node) {
11
- return node.flags & -8459 | node.subtreeFlags;
12
- }
13
- function clearTransientFlags(node) {
14
- node.flags &= StaticFlagsMask;
15
- node.subtreeFlags &= StaticFlagsMask;
16
- }
17
- //#endregion
1
+ import { A as transitionTypeHooks, C as markRootUpdated, D as runWithPriority, E as requestUpdateLane, F as StaticFlagsMask, I as StoreConsistencyFlag, L as ViewTransitionStaticFlag, M as AssetFlag, N as ContextPropagationFlag, O as runWithTransition, P as HoistedStaticFlag, R as childSubtreeFlags, S as markRootSuspended, T as mergeLanes, _ as isSyncLane, b as markRootFinished, c as SelectiveHydrationLane, d as createLaneMap, f as getHighestPriorityLane, g as includesSomeLane, h as includesOnlyTransitions, i as DeferredLane, j as tagFor, k as runWithTransitionLane, l as claimNextRetryLane, m as getNextLanes, n as walkFiberSubtree, o as OffscreenLane, p as getLaneSchedulerPriority, s as RetryLanes, t as walkFiberForest, u as claimNextTransitionLane, w as markStarvedLanesAsExpired, x as markRootPinged, y as markRootEntangled, z as clearTransientFlags } from "./fiber-traversal-BHyIAyG9.js";
2
+ import { a as shouldYieldToHost, i as scheduleCallback, n as now, r as requestPaint } from "./scheduler-WVeIVb_n.js";
3
+ import { Fragment, isValidElement } from "@bgub/fig";
4
+ import { attachDataStore, collectChildren, dataResourceKeysForError, invalidChildError, isPortal, isThenable, readThenable, setCurrentDataStore, setCurrentDispatcher, setTransitionHandler } from "@bgub/fig/internal";
18
5
  //#region src/commit-index.ts
19
- function createCommitIndex() {
20
- return [];
21
- }
22
- function commitIndexCheckpoint(index) {
23
- return index.length;
24
- }
25
6
  function recordCommitWork(index, node, flags = 0) {
26
7
  node.flags |= flags;
27
8
  if ((node.flags & 256) !== 0) return;
@@ -30,448 +11,38 @@ function recordCommitWork(index, node, flags = 0) {
30
11
  }
31
12
  function rollbackCommitIndex(index, checkpoint) {
32
13
  if (checkpoint === void 0 || checkpoint >= index.length) return;
33
- const start = checkpoint;
34
- for (let offset = start; offset < index.length; offset += 1) index[offset].flags &= -257;
14
+ for (let offset = checkpoint; offset < index.length; offset += 1) index[offset].flags &= -257;
35
15
  index.length = checkpoint;
36
16
  }
37
17
  function clearCommitIndex(index) {
38
18
  for (const node of index) node.flags &= -257;
39
19
  index.length = 0;
40
20
  }
41
- function tagFor(element) {
42
- if (typeof element.type === "string") return 1;
43
- if (element.type === Fragment) return 4;
44
- if (isAssets(element.type)) return 9;
45
- if (isContext(element.type)) return 5;
46
- if (isSuspense(element.type)) return 6;
47
- if (isActivity(element.type)) return 10;
48
- if (isErrorBoundary(element.type)) return 7;
49
- if (isViewTransition(element.type)) return 11;
50
- return 3;
21
+ //#endregion
22
+ //#region src/devtools-internal.ts
23
+ function devtoolsTypeName(type, fallback) {
24
+ if (typeof type === "string") return type;
25
+ if (type === Fragment) return "Fragment";
26
+ if (typeof type !== "function") return fallback;
27
+ const namedType = type;
28
+ if (typeof namedType.displayName === "string" && namedType.displayName !== "") return namedType.displayName;
29
+ if (typeof namedType.name === "string" && namedType.name !== "") return namedType.name;
30
+ return fallback;
51
31
  }
52
32
  function isEffectHook(kind) {
53
33
  return kind <= 2;
54
34
  }
55
- const priorityTimeouts = {
56
- [1]: -1,
57
- [2]: 250,
58
- [3]: 5e3,
59
- [4]: 1e4,
60
- [5]: 1073741823
61
- };
62
- const frameInterval = 5;
63
- function compare(a, b) {
64
- return a.expirationTime - b.expirationTime || a.id - b.id;
65
- }
66
- var MinHeap = class {
67
- items = [];
68
- push(value) {
69
- this.items.push(value);
70
- this.siftUp(this.items.length - 1);
71
- }
72
- peek() {
73
- return this.items[0] ?? null;
74
- }
75
- pop() {
76
- const first = this.items[0];
77
- const last = this.items.pop();
78
- if (first === void 0 || last === void 0) return null;
79
- if (first !== last) {
80
- this.items[0] = last;
81
- this.siftDown(0);
82
- }
83
- return first;
84
- }
85
- siftUp(index) {
86
- const value = this.items[index];
87
- while (index > 0) {
88
- const parentIndex = index - 1 >>> 1;
89
- const parent = this.items[parentIndex];
90
- if (compare(parent, value) <= 0) return;
91
- this.items[parentIndex] = value;
92
- this.items[index] = parent;
93
- index = parentIndex;
94
- }
95
- }
96
- siftDown(index) {
97
- const length = this.items.length;
98
- const value = this.items[index];
99
- while (index < length) {
100
- const leftIndex = index * 2 + 1;
101
- const rightIndex = leftIndex + 1;
102
- let smallest = index;
103
- if (leftIndex < length && compare(this.items[leftIndex], this.items[smallest]) < 0) smallest = leftIndex;
104
- if (rightIndex < length && compare(this.items[rightIndex], this.items[smallest]) < 0) smallest = rightIndex;
105
- if (smallest === index) return;
106
- this.items[index] = this.items[smallest];
107
- this.items[smallest] = value;
108
- index = smallest;
109
- }
110
- }
111
- };
112
- const taskQueue = new MinHeap();
113
- let taskId = 1;
114
- let messageLoopRunning = false;
115
- let needsPaint = false;
116
- let startTime = -1;
117
- let actQueue = null;
118
- let actScopeDepth = 0;
119
- let flushingActQueue = false;
120
- const actFlushLimit = 1e3;
121
- function now() {
122
- return globalThis.performance?.now?.() ?? Date.now();
123
- }
124
- function shouldYieldToHost() {
125
- return needsPaint || now() - startTime >= frameInterval;
126
- }
127
- function requestPaint() {
128
- needsPaint = true;
129
- }
130
- function scheduleCallback(priority, callback) {
131
- const task = {
132
- id: taskId++,
133
- callback,
134
- expirationTime: now() + priorityTimeouts[priority]
135
- };
136
- if (actQueue !== null) {
137
- actQueue.push(task);
138
- return { cancel() {
139
- task.callback = null;
140
- } };
141
- }
142
- taskQueue.push(task);
143
- requestHostCallback();
144
- return { cancel() {
145
- task.callback = null;
146
- } };
147
- }
148
- async function act(callback) {
149
- const previousActQueue = actQueue;
150
- const previousActScopeDepth = actScopeDepth;
151
- const queue = previousActQueue ?? [];
152
- actQueue = queue;
153
- actScopeDepth = previousActScopeDepth + 1;
154
- try {
155
- const result = await callback();
156
- actScopeDepth = previousActScopeDepth;
157
- if (previousActScopeDepth === 0) try {
158
- await flushActQueueUntilSettled(queue);
159
- } finally {
160
- actQueue = previousActQueue;
161
- }
162
- else actQueue = previousActQueue;
163
- return result;
164
- } catch (error) {
165
- actScopeDepth = previousActScopeDepth;
166
- actQueue = previousActQueue;
167
- throw error;
168
- }
169
- }
170
- async function flushActQueueUntilSettled(queue) {
171
- for (let flushes = 0; flushes < actFlushLimit; flushes += 1) {
172
- flushActQueue(queue);
173
- await Promise.resolve();
174
- if (hasActWork(queue)) continue;
175
- await waitForActMacrotask();
176
- if (!hasActWork(queue)) {
177
- queue.length = 0;
178
- return;
179
- }
180
- }
181
- throw new Error("act() exceeded the scheduled work flush limit.");
182
- }
183
- function flushActQueue(queue) {
184
- if (flushingActQueue) return;
185
- flushingActQueue = true;
186
- try {
187
- let task = takeNextActTask(queue);
188
- while (task !== null) {
189
- const callback = task.callback;
190
- if (callback !== null) {
191
- task.callback = null;
192
- needsPaint = false;
193
- startTime = now();
194
- const continuation = callback();
195
- if (typeof continuation === "function") {
196
- task.callback = continuation;
197
- queue.push(task);
198
- }
199
- }
200
- task = takeNextActTask(queue);
201
- }
202
- } finally {
203
- flushingActQueue = false;
204
- }
205
- }
206
- function hasActWork(queue) {
207
- return queue.some((task) => task.callback !== null);
208
- }
209
- function takeNextActTask(queue) {
210
- let nextIndex = -1;
211
- for (let index = 0; index < queue.length; index += 1) {
212
- const task = queue[index];
213
- if (task.callback === null) continue;
214
- if (nextIndex === -1 || compare(task, queue[nextIndex]) < 0) nextIndex = index;
215
- }
216
- if (nextIndex === -1) {
217
- queue.length = 0;
218
- return null;
219
- }
220
- const [task] = queue.splice(nextIndex, 1);
221
- return task;
222
- }
223
- function waitForActMacrotask() {
224
- return new Promise((resolve) => {
225
- if (typeof setImmediate === "function") setImmediate(resolve);
226
- else setTimeout(resolve, 0);
227
- });
228
- }
229
- function requestHostCallback() {
230
- if (messageLoopRunning) return;
231
- messageLoopRunning = true;
232
- scheduleHostCallback();
233
- }
234
- function performWorkUntilDeadline() {
235
- needsPaint = false;
236
- startTime = now();
237
- let hasMoreWork = false;
238
- try {
239
- hasMoreWork = flushWork(startTime);
240
- } finally {
241
- if (hasMoreWork) scheduleHostCallback();
242
- else messageLoopRunning = false;
243
- }
244
- }
245
- let channel = null;
246
- const scheduleHostCallback = typeof setImmediate === "function" ? () => void setImmediate(performWorkUntilDeadline) : typeof MessageChannel === "function" ? () => {
247
- if (channel === null) {
248
- channel = new MessageChannel();
249
- channel.port1.onmessage = () => performWorkUntilDeadline();
250
- }
251
- channel.port2.postMessage(null);
252
- } : () => void setTimeout(performWorkUntilDeadline, 0);
253
- function flushWork(currentTime) {
254
- let task = taskQueue.peek();
255
- while (task !== null) {
256
- if (task.expirationTime > currentTime && shouldYieldToHost()) break;
257
- const callback = task.callback;
258
- if (callback === null) taskQueue.pop();
259
- else {
260
- task.callback = null;
261
- const continuation = callback();
262
- if (typeof continuation === "function") task.callback = continuation;
263
- else if (task === taskQueue.peek()) taskQueue.pop();
264
- }
265
- task = taskQueue.peek();
266
- }
267
- return task !== null;
268
- }
269
- const RetryLane1 = 1 << 22;
270
- const SelectiveHydrationLane = 1 << 26;
271
- const OffscreenLane = 1 << 29;
272
- const DeferredLane = 1 << 30;
273
- const AllTransitionLanes = 4194048;
274
- const RetryLanes = 62914560;
275
- const syncLaneExpirationMs = 250;
276
- const transitionLaneExpirationMs = 5e3;
277
- let currentUpdateLane = 32;
278
- let nextTransitionLane = 256;
279
- let nextRetryLane = RetryLane1;
280
- let asyncTransitionLanes = 0;
281
- const asyncTransitionLaneCounts = createLaneMap(0);
282
- function createLaneMap(initial) {
283
- return Array.from({ length: 31 }, () => initial);
284
- }
285
- function mergeLanes(a, b) {
286
- return a | b;
287
- }
288
- function includesSomeLane(set, subset) {
289
- return (set & subset) !== 0;
290
- }
291
- function getHighestPriorityLane(lanes) {
292
- return lanes & -lanes;
293
- }
294
- function getHighestPriorityLanes(lanes) {
295
- const lane = getHighestPriorityLane(lanes);
296
- if (includesSomeLane(4194048, lane)) return lanes & AllTransitionLanes;
297
- if (includesSomeLane(62914560, lane)) return lanes & RetryLanes;
298
- return lane;
299
- }
300
- function getNextLanes(root, wipLanes = 0) {
301
- const pending = root.pendingLanes;
302
- if (pending === 0) return 0;
303
- const unblocked = pending & ~root.suspendedLanes;
304
- const pinged = pending & root.pingedLanes;
305
- let next = root.expiredLanes & unblocked;
306
- if (next === 0) {
307
- next = getHighestPriorityLanes(unblocked);
308
- if (next === 0) {
309
- const expiredPinged = root.expiredLanes & pinged;
310
- next = expiredPinged !== 0 ? expiredPinged : getHighestPriorityLanes(pinged);
311
- }
312
- }
313
- if (next === 0) return 0;
314
- if (wipLanes !== 0 && wipLanes !== next && !includesSomeLane(root.expiredLanes, wipLanes) && getHighestPriorityLane(next) >= getHighestPriorityLane(wipLanes)) return wipLanes;
315
- return getEntangledLanes(root, next);
316
- }
317
- function getEntangledLanes(root, lanes) {
318
- let entangled = lanes;
319
- let visited = 0;
320
- let laneSet = entangled & root.entangledLanes;
321
- while (laneSet !== 0) {
322
- const index = laneToIndex(laneSet);
323
- const lane = 1 << index;
324
- entangled |= root.entanglements[index];
325
- visited |= lane;
326
- laneSet = entangled & root.entangledLanes & ~visited;
327
- }
328
- return entangled;
329
- }
330
- function markRootUpdated(root, lane) {
331
- root.pendingLanes |= lane;
332
- if (lane !== 268435456) {
333
- root.suspendedLanes = 0;
334
- root.pingedLanes = 0;
335
- }
336
- }
337
- function markRootFinished(root, remainingLanes) {
338
- const noLongerPending = root.pendingLanes & ~remainingLanes;
339
- root.pendingLanes = remainingLanes;
340
- root.suspendedLanes = 0;
341
- root.pingedLanes = 0;
342
- root.expiredLanes &= remainingLanes;
343
- root.entangledLanes &= remainingLanes;
344
- let lanes = noLongerPending;
345
- while (lanes !== 0) {
346
- const index = laneToIndex(lanes);
347
- const lane = 1 << index;
348
- root.entanglements[index] = 0;
349
- root.expirationTimes[index] = -1;
350
- lanes &= ~lane;
351
- }
352
- }
353
- function markRootSuspended(root, lanes) {
354
- root.suspendedLanes |= lanes;
355
- root.pingedLanes &= ~lanes;
356
- let laneSet = lanes;
357
- while (laneSet !== 0) {
358
- const index = laneToIndex(laneSet);
359
- const lane = 1 << index;
360
- root.expirationTimes[index] = -1;
361
- laneSet &= ~lane;
362
- }
363
- }
364
- function markRootPinged(root, lanes) {
365
- root.pingedLanes |= root.suspendedLanes & lanes;
366
- }
367
- function markRootEntangled(root, lanes) {
368
- root.entangledLanes |= lanes;
369
- let laneSet = lanes;
370
- while (laneSet !== 0) {
371
- const index = laneToIndex(laneSet);
372
- const lane = 1 << index;
373
- root.entanglements[index] |= lanes;
374
- laneSet &= ~lane;
375
- }
376
- }
377
- function markStarvedLanesAsExpired(root, currentTime) {
378
- let lanes = root.pendingLanes & -62914561;
379
- while (lanes !== 0) {
380
- const index = laneToIndex(lanes);
381
- const lane = 1 << index;
382
- const expiration = root.expirationTimes[index];
383
- if (expiration === -1) {
384
- if (!includesSomeLane(root.suspendedLanes, lane) || includesSomeLane(root.pingedLanes, lane)) root.expirationTimes[index] = computeExpirationTime(lane, currentTime);
385
- } else if (expiration <= currentTime) root.expiredLanes |= lane;
386
- lanes &= ~lane;
387
- }
388
- }
389
- function claimNextTransitionLane() {
390
- const lane = nextTransitionLane;
391
- nextTransitionLane <<= 1;
392
- if (!includesSomeLane(261888, nextTransitionLane)) nextTransitionLane = 256;
393
- return lane;
394
- }
395
- function claimNextRetryLane() {
396
- const lane = nextRetryLane;
397
- nextRetryLane <<= 1;
398
- if (!includesSomeLane(62914560, nextRetryLane)) nextRetryLane = RetryLane1;
399
- return lane;
400
- }
401
- function isSyncLane(lane) {
402
- return includesSomeLane(3, lane);
403
- }
404
- function includesOnlyTransitions(lanes) {
405
- return (lanes & AllTransitionLanes) === lanes;
406
- }
407
- function getLaneSchedulerPriority(lane) {
408
- if (includesSomeLane(3, lane)) return 1;
409
- if (includesSomeLane(76, lane)) return 2;
410
- if (includesSomeLane(71303088, lane)) return 3;
411
- if (includesSomeLane(62914560, lane)) return 4;
412
- return 5;
413
- }
414
- function requestUpdateLane() {
415
- if (currentUpdateLane === 32 && asyncTransitionLanes !== 0) return getHighestPriorityLane(asyncTransitionLanes);
416
- return currentUpdateLane;
417
- }
418
- function runWithPriority(lane, callback) {
419
- const previousLane = currentUpdateLane;
420
- currentUpdateLane = lane;
421
- try {
422
- return callback();
423
- } finally {
424
- currentUpdateLane = previousLane;
425
- }
426
- }
427
- function runWithTransition(callback) {
428
- return runWithTransitionLane(includesSomeLane(4194048, currentUpdateLane) ? currentUpdateLane : claimNextTransitionLane(), callback);
429
- }
430
- function runWithTransitionLane(lane, callback) {
431
- const result = runWithPriority(lane, callback);
432
- if (isThenable(result)) {
433
- const release = trackAsyncTransitionLane(lane);
434
- result.then(release, release);
435
- }
436
- return result;
437
- }
438
- function trackAsyncTransitionLane(lane) {
439
- const index = laneToIndex(lane);
440
- asyncTransitionLaneCounts[index] += 1;
441
- asyncTransitionLanes |= lane;
442
- return () => releaseAsyncTransitionLane(lane, index);
443
- }
444
- function releaseAsyncTransitionLane(lane, index) {
445
- asyncTransitionLaneCounts[index] = Math.max(0, asyncTransitionLaneCounts[index] - 1);
446
- if (asyncTransitionLaneCounts[index] === 0) asyncTransitionLanes &= ~lane;
447
- }
448
- function computeExpirationTime(lane, currentTime) {
449
- if (includesSomeLane(79, lane)) return currentTime + syncLaneExpirationMs;
450
- if (includesSomeLane(4194224, lane)) return currentTime + transitionLaneExpirationMs;
451
- return -1;
452
- }
453
- function laneToIndex(lanes) {
454
- return 31 - Math.clz32(lanes);
455
- }
456
- //#endregion
457
- //#region src/fiber-traversal.ts
458
- function walkFiberForest(node, visitor) {
459
- walkFiberTree(node, true, visitor);
460
- }
461
- function walkFiberSubtree(node, visitor) {
462
- walkFiberTree(node, false, visitor);
463
- }
464
- function walkFiberTree(node, includeRootSiblings, visitor) {
465
- const stack = [];
466
- let cursor = node;
467
- while (cursor !== null) {
468
- const shouldDescend = visitor(cursor) !== false && cursor.child !== null;
469
- if ((includeRootSiblings || cursor !== node) && cursor.sibling !== null) stack.push(cursor.sibling);
470
- cursor = shouldDescend ? cursor.child : stack.pop() ?? null;
471
- }
472
- }
473
35
  //#endregion
474
36
  //#region src/hook-queue.ts
37
+ var HookUpdate = class {
38
+ action;
39
+ lane;
40
+ next = this;
41
+ constructor(action, lane) {
42
+ this.action = action;
43
+ this.lane = lane;
44
+ }
45
+ };
475
46
  function mergeQueues(baseQueue, pendingQueue) {
476
47
  if (baseQueue === null) return pendingQueue;
477
48
  const baseFirst = baseQueue.next;
@@ -480,24 +51,19 @@ function mergeQueues(baseQueue, pendingQueue) {
480
51
  return pendingQueue;
481
52
  }
482
53
  function cloneUpdateNode(update) {
483
- const clone = {
484
- action: update.action,
485
- lane: update.lane,
486
- next: null
487
- };
488
- clone.next = clone;
489
- return clone;
54
+ return new HookUpdate(update.action, update.lane);
490
55
  }
491
56
  function cloneQueue(queue) {
492
57
  return queue === null ? null : cloneQueueNodes(queue);
493
58
  }
494
59
  function cloneQueueNodes(queue) {
495
- let clone = null;
496
- let update = queue.next;
497
- do {
60
+ const first = queue.next;
61
+ let clone = cloneUpdateNode(first);
62
+ let update = first.next;
63
+ while (update !== first) {
498
64
  clone = mergeQueues(clone, cloneUpdateNode(update));
499
65
  update = update.next;
500
- } while (update !== queue.next);
66
+ }
501
67
  return clone;
502
68
  }
503
69
  function clearQueueLanes(queue) {
@@ -548,7 +114,7 @@ function hostTextContentPart(node) {
548
114
  }
549
115
  if (node === null || node === void 0 || typeof node === "boolean") return EmptyHostTextContent;
550
116
  if (typeof node === "string" || typeof node === "number") return String(node);
551
- if (isValidElement(node) || isPortal(node)) return NonTextHostContent;
117
+ if (isValidElement(node) || isPortal(node) || isThenable(node)) return NonTextHostContent;
552
118
  throw invalidChildError(node);
553
119
  }
554
120
  //#endregion
@@ -591,6 +157,9 @@ function createRootDataStore(host) {
591
157
  preloadData(resource, ...args) {
592
158
  installStore(resource).preloadData(resource, ...args);
593
159
  },
160
+ ensureData(resource, ...args) {
161
+ return installStore(resource).ensureData(resource, ...args);
162
+ },
594
163
  invalidateData(resource, ...args) {
595
164
  installStore(resource).invalidateData(resource, ...args);
596
165
  },
@@ -627,6 +196,9 @@ function createRootDataStore(host) {
627
196
  inspectDataEntries() {
628
197
  return inner?.inspectDataEntries() ?? [];
629
198
  },
199
+ inspectDataDependencyCanonicalKeys(owner) {
200
+ return inner?.inspectDataDependencyCanonicalKeys(owner) ?? [];
201
+ },
630
202
  snapshot() {
631
203
  return inner?.snapshot() ?? buffered?.slice() ?? [];
632
204
  }
@@ -661,6 +233,7 @@ function createRenderer(host) {
661
233
  const pendingRoots = /* @__PURE__ */ new Set();
662
234
  const batchedRoots = /* @__PURE__ */ new Set();
663
235
  const abandonedHydrationBoundaries = /* @__PURE__ */ new WeakSet();
236
+ let commitCoordinator = null;
664
237
  let batchDepth = 0;
665
238
  let flushingSyncWork = false;
666
239
  let commitDepth = 0;
@@ -674,12 +247,22 @@ function createRenderer(host) {
674
247
  let activityHostConfig = null;
675
248
  let activityHydrationHostConfig = null;
676
249
  let hoistedAssetHostConfig = null;
677
- const viewTransitionHost = host.viewTransition ?? null;
678
250
  let renderingFiber = null;
679
251
  let currentHook = null;
680
252
  let workInProgressHook = null;
681
253
  let localIdCounter = 0;
682
- let viewTransitionAutoNameCounter = 0;
254
+ function installCommitCoordinator(coordinator) {
255
+ if (commitCoordinator === coordinator) return;
256
+ if (commitCoordinator !== null) throw new Error(`Cannot install commit coordinator "${coordinator.name}": commit coordination is already owned by "${commitCoordinator.name}".`);
257
+ commitCoordinator = coordinator;
258
+ }
259
+ function commitPriority(lanes) {
260
+ const lane = getHighestPriorityLane(lanes);
261
+ if (includesSomeLane(130023424, lane)) return "suspense";
262
+ if (includesSomeLane(1077935872, lane)) return "transition";
263
+ if (includesSomeLane(805306368, lane)) return "idle";
264
+ return "blocking";
265
+ }
683
266
  const dispatcher = {
684
267
  useState: updateStateHook,
685
268
  useActionState: updateActionStateHook,
@@ -728,7 +311,7 @@ function createRenderer(host) {
728
311
  function rootForContainer(container, request) {
729
312
  if (roots.has(container)) throw duplicateRootError(request.kind);
730
313
  if (request.kind === "hydration") requireHydrationHostConfig();
731
- const root = createFiberRoot(container, request.options ?? {});
314
+ const root = createFiberRoot(container, request.options);
732
315
  roots.set(container, root);
733
316
  if (request.kind === "hydration") {
734
317
  root.isHydrating = true;
@@ -739,18 +322,20 @@ function createRenderer(host) {
739
322
  }
740
323
  function createFiberRoot(container, options) {
741
324
  const current = fiber(0, null, null, { children: null }, null);
742
- const dataStore = createRootDataStore({
325
+ const dataStoreHost = {
743
326
  getLane: requestUpdateLane,
744
327
  partition: options.dataPartition,
745
328
  schedule(owner, lane) {
746
329
  scheduleFiber(owner, hiddenSubtreeLane(owner, lane));
747
330
  }
748
- });
331
+ };
332
+ const dataStore = options.dataStore === void 0 ? createRootDataStore(dataStoreHost) : attachDataStore(options.dataStore, dataStoreHost, options.initialData);
749
333
  const root = {
750
334
  container,
751
335
  current,
752
336
  element: null,
753
337
  identifierPrefix: options.identifierPrefix ?? "",
338
+ nextClientId: 0,
754
339
  devtools: options.devtools ?? true,
755
340
  pendingLanes: 0,
756
341
  suspendedLanes: 0,
@@ -764,8 +349,8 @@ function createRenderer(host) {
764
349
  wip: null,
765
350
  finishedWork: null,
766
351
  renderLanes: 0,
767
- pendingViewTransitionCommit: false,
768
- parkedViewTransitionCommit: false,
352
+ pendingCoordinatedCommit: false,
353
+ parkedCoordinatedCommit: false,
769
354
  dataStore,
770
355
  contextValues: /* @__PURE__ */ new Map(),
771
356
  contextStack: [],
@@ -782,7 +367,7 @@ function createRenderer(host) {
782
367
  uncaughtErrorInfo: null,
783
368
  commitEffectPhases: 0,
784
369
  needsCommitDeletions: false,
785
- commitIndex: createCommitIndex(),
370
+ commitIndex: [],
786
371
  committedCaughtErrors: [],
787
372
  isHydrating: false,
788
373
  isHydrationRoot: false,
@@ -796,7 +381,7 @@ function createRenderer(host) {
796
381
  clearContainerBeforeCommit: false,
797
382
  hydrationInitialElement: NoHydrationInitialElement
798
383
  };
799
- if (options.initialData !== void 0) dataStore.hydrate(options.initialData);
384
+ if (options.dataStore === void 0 && options.initialData !== void 0) dataStore.hydrate(options.initialData);
800
385
  current.stateNode = root;
801
386
  return root;
802
387
  }
@@ -912,9 +497,14 @@ function createRenderer(host) {
912
497
  }
913
498
  function markRootPending(root, lane) {
914
499
  markRootUpdated(root, lane);
500
+ transitionTypeHooks.record?.(root, lane);
915
501
  pendingRoots.add(root);
916
502
  if (currentCommitEffectPhase === 1 && isSyncLane(lane)) needsPostCommitSyncFlush = true;
917
503
  }
504
+ function markRootCompleted(root, remainingLanes) {
505
+ markRootFinished(root, remainingLanes);
506
+ transitionTypeHooks.complete?.(root, remainingLanes);
507
+ }
918
508
  function markCommitEffectPhase(root, phase) {
919
509
  root.commitEffectPhases |= 1 << phase;
920
510
  }
@@ -923,7 +513,7 @@ function createRenderer(host) {
923
513
  else scheduleRoot(root);
924
514
  }
925
515
  function scheduleRoot(root) {
926
- if (root.pendingViewTransitionCommit) return;
516
+ if (root.pendingCoordinatedCommit) return;
927
517
  markStarvedLanesAsExpired(root, now());
928
518
  const nextLanes = getNextLanes(root, root.renderLanes);
929
519
  if (nextLanes === 0) {
@@ -989,6 +579,13 @@ function createRenderer(host) {
989
579
  performRoot(root, true);
990
580
  return;
991
581
  }
582
+ if (host.shouldRecoverSuspenseMismatchAtRoot?.(root.container, state.boundary) === true) {
583
+ markHydrationRecovery(root, "root");
584
+ state.boundary.forceClientRender = true;
585
+ forceClientRender(root);
586
+ performRoot(root, true);
587
+ return;
588
+ }
992
589
  markHydrationRecovery(root, "suspense");
993
590
  state.boundary.forceClientRender = true;
994
591
  deactivateHydration(root);
@@ -1007,14 +604,14 @@ function createRenderer(host) {
1007
604
  root.hydrationInitialElement = NoHydrationInitialElement;
1008
605
  }
1009
606
  function performRootWork(root, forceSync) {
1010
- if (root.pendingViewTransitionCommit) return;
607
+ if (root.pendingCoordinatedCommit) return;
1011
608
  if (root.pendingLanes === 0 && root.wip === null) {
1012
609
  pendingRoots.delete(root);
1013
610
  return;
1014
611
  }
1015
612
  flushPendingReactiveEffects(root);
1016
- if (root.parkedViewTransitionCommit) {
1017
- root.parkedViewTransitionCommit = false;
613
+ if (root.parkedCoordinatedCommit) {
614
+ root.parkedCoordinatedCommit = false;
1018
615
  if (!((root.pendingLanes & ~root.renderLanes) !== 0) && root.wip === null && root.finishedWork !== null) {
1019
616
  if (commitRoot(root, root.finishedWork)) return;
1020
617
  finishRootWork(root);
@@ -1127,7 +724,7 @@ function createRenderer(host) {
1127
724
  }
1128
725
  function begin(node) {
1129
726
  const root = rootOf(node);
1130
- if (node.tag === 6 || node.tag === 7) node.commitIndexCheckpoint = commitIndexCheckpoint(root.commitIndex);
727
+ if (node.tag === 6 || node.tag === 7) node.commitIndexCheckpoint = root.commitIndex.length;
1131
728
  if (canBailout(node, root)) {
1132
729
  let hasChildWork = includesSomeLane(node.childLanes, root.renderLanes);
1133
730
  if (!hasChildWork) hasChildWork = lazilyPropagateParentContextChanges(node, root);
@@ -1149,6 +746,10 @@ function createRenderer(host) {
1149
746
  renderFunction(node, root);
1150
747
  return;
1151
748
  }
749
+ if (node.tag === 12) {
750
+ reconcileCurrentChildren(node, readThenable(node.props.thenable), root);
751
+ return;
752
+ }
1152
753
  if (node.tag === 2) {
1153
754
  if (tryHydrateText(node, root)) return;
1154
755
  node.stateNode ??= host.createTextInstance(String(node.props.nodeValue));
@@ -1157,11 +758,12 @@ function createRenderer(host) {
1157
758
  if (node.tag === 1) {
1158
759
  const type = String(node.type);
1159
760
  const children = hostChildren(node.props);
1160
- if (tryHydrateInstance(node, root)) {
761
+ const hoisted = resolveHoistedFiber(node, root);
762
+ if (!hoisted && tryHydrateInstance(node, root)) {
1161
763
  reconcileCurrentChildren(node, children, root);
1162
764
  return;
1163
765
  }
1164
- node.stateNode ??= host.createInstance(type, node.props, hostParent(node));
766
+ if (!hoisted) node.stateNode ??= host.createInstance(type, node.props, hostParent(node));
1165
767
  reconcileCurrentChildren(node, children === null || shouldUseHostTextContent(node, root) ? null : children, root);
1166
768
  return;
1167
769
  }
@@ -1236,10 +838,6 @@ function createRenderer(host) {
1236
838
  const hydrationHost = requireHydrationHostConfig();
1237
839
  const hydratable = root.nextHydratableInstance;
1238
840
  const type = String(node.type);
1239
- if (isHoistedFiber(node)) {
1240
- node.flags |= 1;
1241
- return false;
1242
- }
1243
841
  if (hydratable === null || !hydrationHost.canHydrateInstance(hydratable, type, node.props)) throwHydrationMismatch(root, node, `<${type}>`);
1244
842
  node.stateNode = hydratable;
1245
843
  recordCommitWork(root.commitIndex, node, 6);
@@ -1281,7 +879,7 @@ function createRenderer(host) {
1281
879
  return;
1282
880
  }
1283
881
  if (!root.isHydrating || root.hydrationParent !== node) return;
1284
- if (root.nextHydratableInstance !== null) throwHydrationMismatch(root, node);
882
+ if (root.nextHydratableInstance !== null && !(node.tag === 1 && host.canRetainHydrationTail?.(node.stateNode) === true)) throwHydrationMismatch(root, node);
1285
883
  const hydrationHost = requireHydrationHostConfig();
1286
884
  root.hydrationParent = nextHydrationParent(node.return);
1287
885
  root.nextHydratableInstance = node.tag === 1 ? hydrationHost.getNextHydratableSibling(node.stateNode) : null;
@@ -1342,19 +940,24 @@ function createRenderer(host) {
1342
940
  function hydrationBypassedHost(node) {
1343
941
  return node.alternate === null && node.stateNode !== null && (node.flags & 4) === 0;
1344
942
  }
1345
- function isHoistedFiber(node) {
1346
- if (node.tag !== 1 || host.isHoistedInstance === void 0) return false;
1347
- if ((node.flags & 8192) !== 0) return false;
1348
- if (!host.isHoistedInstance(String(node.type), node.props)) {
1349
- node.flags |= NotHoistedFlag;
1350
- return false;
1351
- }
943
+ function resolveHoistedFiber(node, root) {
944
+ if (isHoistedFiber(node)) return true;
945
+ if (node.tag !== 1 || node.stateNode !== null || host.resolveHoistedInstance === void 0) return false;
946
+ const hydrating = shouldHydrateFiber(root, node);
947
+ const instance = host.resolveHoistedInstance(String(node.type), node.props, hostParent(node));
948
+ if (instance === null) return false;
1352
949
  requireHoistedAssetHostConfig();
950
+ node.stateNode = instance;
951
+ node.flags |= HoistedStaticFlag;
952
+ if (hydrating) node.flags |= 1;
1353
953
  return true;
1354
954
  }
955
+ function isHoistedFiber(node) {
956
+ return node.tag === 1 && (node.flags & 8192) !== 0;
957
+ }
1355
958
  function requireHoistedAssetHostConfig() {
1356
959
  if (hoistedAssetHostConfig !== null) return hoistedAssetHostConfig;
1357
- if (host.isHoistedInstance === void 0 || host.commitHoistedInstance === void 0 || host.removeHoistedInstance === void 0 || host.updateHoistedInstance === void 0) throw new Error("Hoisted assets are not supported by this renderer.");
960
+ if (host.resolveHoistedInstance === void 0 || host.commitHoistedInstance === void 0 || host.removeHoistedInstance === void 0 || host.updateHoistedInstance === void 0) throw new Error("Hoisted assets are not supported by this renderer.");
1358
961
  hoistedAssetHostConfig = host;
1359
962
  return hoistedAssetHostConfig;
1360
963
  }
@@ -1394,7 +997,7 @@ function createRenderer(host) {
1394
997
  node.boundaryState = previousSuspenseState;
1395
998
  return;
1396
999
  }
1397
- hydrateDehydratedSuspenseBoundary(node, previousSuspenseState.boundary);
1000
+ hydrateDehydratedSuspenseBoundary(node, previousSuspenseState);
1398
1001
  return;
1399
1002
  }
1400
1003
  if (tryDehydrateSuspenseBoundary(node)) return;
@@ -1474,6 +1077,7 @@ function createRenderer(host) {
1474
1077
  if (boundary === null) return false;
1475
1078
  node.boundaryState = {
1476
1079
  boundary,
1080
+ idPath: hydrationIdPath(root, node),
1477
1081
  kind: "dehydrated",
1478
1082
  wasPending: boundary.status === "pending"
1479
1083
  };
@@ -1481,7 +1085,8 @@ function createRenderer(host) {
1481
1085
  root.nextHydratableInstance = nextAfterSuspenseBoundary(boundary);
1482
1086
  return true;
1483
1087
  }
1484
- function hydrateDehydratedSuspenseBoundary(node, boundary) {
1088
+ function hydrateDehydratedSuspenseBoundary(node, state) {
1089
+ const boundary = state.boundary;
1485
1090
  abandonedHydrationBoundaries.delete(node);
1486
1091
  if (node.alternate !== null) abandonedHydrationBoundaries.delete(node.alternate);
1487
1092
  if (!boundary.forceClientRender) {
@@ -1493,11 +1098,7 @@ function createRenderer(host) {
1493
1098
  return;
1494
1099
  }
1495
1100
  if (boundary.status === "pending") {
1496
- node.boundaryState = {
1497
- boundary,
1498
- kind: "dehydrated",
1499
- wasPending: true
1500
- };
1101
+ node.boundaryState = state;
1501
1102
  return;
1502
1103
  }
1503
1104
  }
@@ -1537,7 +1138,10 @@ function createRenderer(host) {
1537
1138
  if (boundary === null) return false;
1538
1139
  requireActivityHydrationHostConfig();
1539
1140
  hasHiddenBoundaries = true;
1540
- state.dehydrated = boundary;
1141
+ state.dehydrated = {
1142
+ boundary,
1143
+ idPath: hydrationIdPath(root, node)
1144
+ };
1541
1145
  root.nextHydratableInstance = requireHydrationHostConfig().getNextHydratableSibling(boundary);
1542
1146
  return true;
1543
1147
  }
@@ -1587,7 +1191,7 @@ function createRenderer(host) {
1587
1191
  }
1588
1192
  function errorBoundaryFallback(node, state) {
1589
1193
  const fallback = node.props.fallback;
1590
- return typeof fallback === "function" ? fallback(state.error, state.info) : fallback;
1194
+ return typeof fallback === "function" && !isThenable(fallback) ? fallback(state.error, state.info) : fallback;
1591
1195
  }
1592
1196
  function beginPortal(node) {
1593
1197
  reconcileCurrentChildren(node, node.props.children);
@@ -1617,7 +1221,7 @@ function createRenderer(host) {
1617
1221
  ...hook.baseState,
1618
1222
  action
1619
1223
  };
1620
- if (queue.dispatch === null) {
1224
+ if (instance.runner === null) {
1621
1225
  const updatePending = (delta, lane) => {
1622
1226
  scheduleHookUpdate(fiber, queue, (state) => ({
1623
1227
  ...state,
@@ -1632,18 +1236,18 @@ function createRenderer(host) {
1632
1236
  value: value.length === 0 ? state.value : value[0]
1633
1237
  }), lane);
1634
1238
  };
1635
- queue.dispatch = ((...args) => {
1239
+ instance.runner = (...args) => {
1636
1240
  if (renderingFiber !== null) throw new Error("Action state updates are not allowed during render.");
1637
1241
  runLatest(instance, fiber, (signal) => instance.action(instance.value, ...args, signal), updatePending, (lane, value, failed) => {
1638
1242
  if (failed) finish(lane, value);
1639
1243
  else finish(lane, NoActionStateError, value);
1640
1244
  });
1641
- });
1245
+ };
1642
1246
  }
1643
1247
  if (hook.memoizedState.error !== NoActionStateError) throw hook.memoizedState.error;
1644
1248
  return [
1645
1249
  hook.memoizedState.value,
1646
- queue.dispatch,
1250
+ instance.runner,
1647
1251
  hook.memoizedState.pending > 0
1648
1252
  ];
1649
1253
  }
@@ -1690,7 +1294,8 @@ function createRenderer(host) {
1690
1294
  start: null
1691
1295
  });
1692
1296
  const queue = hook.queue;
1693
- if (hook.memoizedState.start === null) {
1297
+ let start = hook.memoizedState.start;
1298
+ if (start === null) {
1694
1299
  const fiber = requireRenderingFiber();
1695
1300
  const updatePending = (delta, lane) => {
1696
1301
  scheduleHookUpdate(fiber, queue, (state) => ({
@@ -1699,7 +1304,7 @@ function createRenderer(host) {
1699
1304
  }), lane);
1700
1305
  };
1701
1306
  const instance = hook.memoizedState.instance;
1702
- hook.memoizedState.start = (callback) => {
1307
+ start = (callback, options) => {
1703
1308
  if (renderingFiber !== null) throw new Error("Transitions cannot be started while rendering a component.");
1704
1309
  runLatest(instance, fiber, callback, updatePending, (lane, value, failed, asynchronous) => {
1705
1310
  updatePending(-1, lane);
@@ -1709,12 +1314,13 @@ function createRenderer(host) {
1709
1314
  throw value;
1710
1315
  });
1711
1316
  }
1712
- });
1317
+ }, options);
1713
1318
  };
1319
+ hook.memoizedState.start = start;
1714
1320
  }
1715
- return [hook.memoizedState.pendingCount > 0, hook.memoizedState.start];
1321
+ return [hook.memoizedState.pendingCount > 0, start];
1716
1322
  }
1717
- function runLatest(instance, fiber, run, updatePending, settled) {
1323
+ function runLatest(instance, fiber, run, updatePending, settled, options) {
1718
1324
  if (retireRun(instance)) updatePending(-1, 32);
1719
1325
  const lane = claimNextTransitionLane();
1720
1326
  const controller = new AbortController();
@@ -1729,7 +1335,7 @@ function createRenderer(host) {
1729
1335
  const store = rootOfOrNull(fiber)?.dataStore;
1730
1336
  let result;
1731
1337
  try {
1732
- const invoke = () => runWithTransitionLane(lane, () => run(controller.signal));
1338
+ const invoke = () => runWithTransitionLane(lane, () => run(controller.signal), options);
1733
1339
  result = store === void 0 ? invoke() : store.run(invoke);
1734
1340
  } catch (error) {
1735
1341
  settle(error, true, false);
@@ -1839,26 +1445,42 @@ function createRenderer(host) {
1839
1445
  }
1840
1446
  function scheduleHookUpdate(fiber, queue, action, lane) {
1841
1447
  lane = hiddenSubtreeLane(fiber, lane);
1842
- const update = {
1843
- action,
1844
- lane,
1845
- next: null
1846
- };
1847
- update.next = update;
1448
+ const update = new HookUpdate(action, lane);
1848
1449
  queue.pending = mergeQueues(queue.pending, update);
1849
1450
  scheduleFiber(fiber, lane);
1850
1451
  }
1851
1452
  function hiddenSubtreeLane(node, lane) {
1852
1453
  if (!hasHiddenBoundaries || lane === 536870912) return lane;
1853
- for (let parent = node.return; parent !== null; parent = parent.return) if (isHiddenBoundaryTag(parent) && fiberActivityState(parent)?.hidden === true) return OffscreenLane;
1454
+ for (let parent = node.return; parent !== null; parent = parent.return) if (parent.tag === 10 && fiberActivityState(parent)?.hidden === true) return OffscreenLane;
1854
1455
  return lane;
1855
1456
  }
1856
1457
  function createFiberId(root, fiber, localId) {
1857
- return `${root.identifierPrefix}fig-${fiberPath(fiber)}-${localId.toString(32)}`;
1458
+ if (!root.isHydrating || insideHydrationExemptHost(fiber)) {
1459
+ const id = root.nextClientId;
1460
+ root.nextClientId += 1;
1461
+ return `${root.identifierPrefix}fig-C-${id.toString(32)}`;
1462
+ }
1463
+ return `${root.identifierPrefix}fig-${hydrationIdPath(root, fiber)}-${localId.toString(32)}`;
1464
+ }
1465
+ function hydrationIdPath(root, fiber) {
1466
+ const suspense = root.hydratingSuspenseBoundary;
1467
+ if (suspense !== null) {
1468
+ const state = fiberSuspenseState(suspense.alternate);
1469
+ if (state?.kind === "dehydrated") return appendIdPath(state.idPath, fiberPath(fiber, suspense));
1470
+ }
1471
+ const activity = root.hydratingActivityBoundary;
1472
+ if (activity !== null) {
1473
+ const base = fiberActivityState(activity)?.dehydrated?.idPath ?? null;
1474
+ if (base !== null) return appendIdPath(base, fiberPath(fiber, activity));
1475
+ }
1476
+ return fiberPath(fiber, null);
1477
+ }
1478
+ function appendIdPath(base, relative) {
1479
+ return relative === "" ? base : `${base}-${relative}`;
1858
1480
  }
1859
- function fiberPath(fiber) {
1481
+ function fiberPath(fiber, stopBefore) {
1860
1482
  const parts = [];
1861
- for (let node = fiber; node !== null && node.tag !== 0; node = node.return) parts.push(node.index.toString(32));
1483
+ for (let node = fiber; node !== null && node !== stopBefore && node.tag !== 0; node = node.return) if (node.tag !== 10 || node.type !== null) parts.push(node.index.toString(32));
1862
1484
  return parts.reverse().join("-");
1863
1485
  }
1864
1486
  function consumePendingHookQueue(root, hook, pending) {
@@ -2020,6 +1642,7 @@ function createRenderer(host) {
2020
1642
  if (host.appendInitialChild !== void 0) node.flags |= 64;
2021
1643
  }
2022
1644
  if (node.tag === 11) node.flags |= ViewTransitionStaticFlag;
1645
+ if (node.tag === 9 && host.commitAssetResources !== void 0 && (node.committedProps === null || node.committedProps.assets !== node.props.assets)) recordCommitWork(rootOf(node).commitIndex, node, AssetFlag);
2023
1646
  node.childLanes = childLanes;
2024
1647
  node.subtreeFlags = subtreeFlags;
2025
1648
  node.contextSubtreeDependencies = contextSubtreeDependencies;
@@ -2160,266 +1783,9 @@ function createRenderer(host) {
2160
1783
  function committedHostProp(name) {
2161
1784
  return name !== "children";
2162
1785
  }
2163
- function isViewTransitionEligibleCommit(root) {
2164
- return !root.clearContainerBeforeCommit && root.renderLanes !== 0 && (root.renderLanes & -1409285889) === 0 && viewTransitionHost !== null;
2165
- }
2166
- function prepareViewTransitionPlan(root, finishedWork) {
2167
- if (!isViewTransitionEligibleCommit(root)) return null;
2168
- if ((finishedWork.subtreeFlags & 4096) === 0 && !root.needsCommitDeletions) return null;
2169
- const plan = {
2170
- newSurfaces: [],
2171
- oldSurfaces: [],
2172
- rootAffected: false
2173
- };
2174
- const exitsByName = /* @__PURE__ */ new Map();
2175
- if (root.needsCommitDeletions) collectDeletedViewTransitions(root, finishedWork, plan, exitsByName);
2176
- const changedBoundaries = attributeQueuedHostUpdates(root, plan);
2177
- collectFinishedViewTransitions(finishedWork.child, false, false, false, changedBoundaries, plan, exitsByName);
2178
- if (plan.oldSurfaces.length === 0 && plan.newSurfaces.length === 0) return null;
2179
- return plan;
2180
- }
2181
- function collectDeletedViewTransitions(root, node, plan, exitsByName) {
2182
- for (const cursor of root.commitIndex) {
2183
- if (cursor.deletions === null) continue;
2184
- for (const deletion of cursor.deletions) collectDeletedViewTransitionFiber(deletion, plan, exitsByName, true);
2185
- }
2186
- }
2187
- function collectDeletedViewTransitionFiber(cursor, plan, exitsByName, collectExit) {
2188
- if (cursor.tag === 8 || isHiddenBoundary(cursor)) return;
2189
- if (cursor.tag === 11) {
2190
- if (explicitViewTransitionName(cursor) !== null) exitsByName.set(viewTransitionName(cursor), cursor);
2191
- if (collectExit) collectViewTransitionSurfaces(cursor, "exit", plan.oldSurfaces, "committed");
2192
- for (let child = cursor.child; child !== null; child = child.sibling) collectDeletedViewTransitionFiber(child, plan, exitsByName, false);
2193
- return;
2194
- }
2195
- if ((cursor.subtreeFlags & 4096) === 0) return;
2196
- for (let child = cursor.child; child !== null; child = child.sibling) collectDeletedViewTransitionFiber(child, plan, exitsByName, collectExit);
2197
- }
2198
- function attributeQueuedHostUpdates(root, plan) {
2199
- let changed = null;
2200
- for (const entry of root.commitIndex) {
2201
- if ((entry.flags & 10) === 0) continue;
2202
- let sawPortal = false;
2203
- let boundary = null;
2204
- for (let parent = entry.return; parent !== null; parent = parent.return) {
2205
- if (parent.tag === 11) {
2206
- boundary = parent;
2207
- break;
2208
- }
2209
- if (parent.tag === 8) sawPortal = true;
2210
- }
2211
- if (boundary === null) plan.rootAffected = true;
2212
- else if (!sawPortal) (changed ??= /* @__PURE__ */ new Set()).add(boundary);
2213
- }
2214
- return changed;
2215
- }
2216
- function collectFinishedViewTransitions(node, placed, insideBoundary, ancestorLayoutChanged, changedBoundaries, plan, exitsByName) {
2217
- let layoutChanged = ancestorLayoutChanged;
2218
- for (let cursor = node; !layoutChanged && cursor !== null; cursor = cursor.sibling) if ((cursor.flags & 1) !== 0 && (cursor.alternate !== null || (cursor.flags & 16) !== 0)) layoutChanged = true;
2219
- for (let cursor = node; cursor !== null; cursor = cursor.sibling) {
2220
- const cursorPlaced = placed || (cursor.flags & 1) !== 0;
2221
- if (!(cursor.tag === 11 || (cursor.subtreeFlags & 4096) !== 0)) {
2222
- if (!insideBoundary && ((cursor.flags | cursor.subtreeFlags) & 175) !== 0) plan.rootAffected = true;
2223
- continue;
2224
- }
2225
- if (isStablyHiddenBoundary(cursor)) continue;
2226
- if (cursor.tag === 11) {
2227
- if (!cursorPlaced && ((cursor.flags | cursor.subtreeFlags) & 4) !== 0) continue;
2228
- if (cursorPlaced) {
2229
- const pairedExit = exitsByName.get(viewTransitionName(cursor));
2230
- if (pairedExit !== void 0) {
2231
- if (!insideBoundary) plan.rootAffected = true;
2232
- collectViewTransitionPair(plan, pairedExit, cursor);
2233
- exitsByName.delete(viewTransitionName(cursor));
2234
- } else if (cursor.alternate !== null) {
2235
- collectViewTransitionSurfaces(cursor.alternate, "update", plan.oldSurfaces, "committed", false);
2236
- collectViewTransitionSurfaces(cursor, "update", plan.newSurfaces, "finished", false);
2237
- } else {
2238
- if (!insideBoundary) plan.rootAffected = true;
2239
- collectViewTransitionSurfaces(cursor, "enter", plan.newSurfaces, "finished");
2240
- }
2241
- collectAppearingPairViewTransitions(cursor.child, plan, exitsByName);
2242
- continue;
2243
- }
2244
- const current = cursor.alternate ?? cursor;
2245
- const contentChanged = viewTransitionChangedOutsideNested(cursor, changedBoundaries);
2246
- if (contentChanged || layoutChanged) {
2247
- collectViewTransitionSurfaces(current, "update", plan.oldSurfaces, "committed", contentChanged);
2248
- collectViewTransitionSurfaces(cursor, "update", plan.newSurfaces, "finished", contentChanged);
2249
- }
2250
- collectFinishedViewTransitions(cursor.child, cursorPlaced, true, contentChanged || layoutChanged, changedBoundaries, plan, exitsByName);
2251
- continue;
2252
- }
2253
- if (cursor.tag !== 8) {
2254
- if (!insideBoundary && (cursor.flags & 175) !== 0) plan.rootAffected = true;
2255
- collectFinishedViewTransitions(cursor.child, cursorPlaced, insideBoundary, layoutChanged || (cursor.flags & 175) !== 0, changedBoundaries, plan, exitsByName);
2256
- }
2257
- }
2258
- }
2259
- function collectAppearingPairViewTransitions(node, plan, exitsByName) {
2260
- if (exitsByName.size === 0) return;
2261
- for (let cursor = node; cursor !== null; cursor = cursor.sibling) {
2262
- if (cursor.tag === 8 || isStablyHiddenBoundary(cursor)) continue;
2263
- if (cursor.tag === 11) {
2264
- const pairedExit = explicitViewTransitionName(cursor) !== null ? exitsByName.get(viewTransitionName(cursor)) : void 0;
2265
- if (pairedExit !== void 0) {
2266
- collectViewTransitionPair(plan, pairedExit, cursor);
2267
- exitsByName.delete(viewTransitionName(cursor));
2268
- }
2269
- }
2270
- collectAppearingPairViewTransitions(cursor.child, plan, exitsByName);
2271
- }
2272
- }
2273
- function collectViewTransitionPair(plan, oldBoundary, newBoundary) {
2274
- removeViewTransitionSurfaces(plan.oldSurfaces, oldBoundary);
2275
- collectViewTransitionSurfaces(oldBoundary, "share", plan.oldSurfaces, "committed");
2276
- collectViewTransitionSurfaces(newBoundary, "share", plan.newSurfaces, "finished");
2277
- }
2278
- function isStablyHiddenBoundary(node) {
2279
- if (!isHiddenBoundary(node)) return false;
2280
- const current = node.alternate;
2281
- return current === null || activityHidden(current.memoizedProps ?? current.props);
2282
- }
2283
- function viewTransitionChangedOutsideNested(boundary, changedBoundaries) {
2284
- if ((boundary.flags & 175) !== 0) return true;
2285
- if (changedBoundaries !== null && changedBoundaries.has(boundary)) return true;
2286
- return subtreeChangedOutsideNested(boundary.child);
2287
- }
2288
- function subtreeChangedOutsideNested(node) {
2289
- for (let cursor = node; cursor !== null; cursor = cursor.sibling) {
2290
- if (cursor.tag === 8) continue;
2291
- if (cursor.tag === 11) continue;
2292
- if ((cursor.flags & 175) !== 0) return true;
2293
- if ((cursor.subtreeFlags & 175) === 0) continue;
2294
- if (subtreeChangedOutsideNested(cursor.child)) return true;
2295
- }
2296
- return false;
2297
- }
2298
- function removeViewTransitionSurfaces(surfaces, boundary) {
2299
- for (let index = surfaces.length - 1; index >= 0; index -= 1) if (surfaces[index].boundary === boundary) surfaces.splice(index, 1);
2300
- }
2301
- function collectViewTransitionSurfaces(boundary, phase, surfaces, propsSource, mustAnimate = true) {
2302
- const className = viewTransitionClass(boundary.props, phase);
2303
- if (className === "none") return;
2304
- const name = viewTransitionName(boundary);
2305
- let index = 0;
2306
- const collect = (node) => {
2307
- for (let cursor = node; cursor !== null; cursor = cursor.sibling) {
2308
- if (cursor.tag === 8) continue;
2309
- if (cursor.tag === 11) continue;
2310
- if (cursor.tag === 1) {
2311
- if (!isHoistedFiber(cursor)) {
2312
- surfaces.push({
2313
- boundary,
2314
- className,
2315
- instance: cursor.stateNode,
2316
- measurement: null,
2317
- mustAnimate,
2318
- name: index === 0 ? name : `${name}_${index}`,
2319
- phase,
2320
- props: viewTransitionSurfaceProps(cursor, propsSource),
2321
- skipped: false
2322
- });
2323
- index += 1;
2324
- }
2325
- continue;
2326
- }
2327
- collect(cursor.child);
2328
- }
2329
- };
2330
- collect(boundary.child);
2331
- }
2332
- function viewTransitionSurfaceProps(node, source) {
2333
- if (source === "committed") return node.committedProps ?? node.memoizedProps ?? node.props;
2334
- return node.memoizedProps ?? node.props;
2335
- }
2336
- function viewTransitionName(node) {
2337
- const props = node.props;
2338
- if (props.name !== void 0 && props.name !== "auto") return props.name;
2339
- const state = node.stateNode;
2340
- state.autoName ??= `fig-vt-${viewTransitionAutoNameCounter++}`;
2341
- return state.autoName;
2342
- }
2343
- function explicitViewTransitionName(node) {
2344
- const name = node.props.name;
2345
- return name === void 0 || name === "auto" ? null : name;
2346
- }
2347
- function viewTransitionClass(props, phase) {
2348
- const viewTransitionProps = props;
2349
- const phaseClass = viewTransitionProps[phase];
2350
- const className = phaseClass === void 0 ? viewTransitionProps.default : phaseClass;
2351
- if (className === void 0 || className === "auto") return null;
2352
- if (className === "none") return "none";
2353
- return className;
2354
- }
2355
- function applyOldViewTransitionSurfaces(plan) {
2356
- if (viewTransitionHost === null) return;
2357
- const measure = viewTransitionHost.measure;
2358
- for (const surface of plan.oldSurfaces) {
2359
- surface.measurement = measure?.(surface.instance) ?? null;
2360
- if (surface.phase === "exit" && surface.measurement !== null && !surface.measurement.inViewport) {
2361
- surface.skipped = true;
2362
- continue;
2363
- }
2364
- viewTransitionHost.apply(surface.instance, surface.name, surface.className);
2365
- }
2366
- }
2367
- function resolveViewTransitionPlan(plan) {
2368
- const result = {
2369
- canceledNames: [],
2370
- cancelRootSnapshot: false
2371
- };
2372
- if (viewTransitionHost === null || plan === null) return result;
2373
- const measure = viewTransitionHost.measure;
2374
- const oldByName = /* @__PURE__ */ new Map();
2375
- for (const surface of plan.oldSurfaces) if (!surface.skipped) oldByName.set(surface.name, surface);
2376
- let rootAffected = plan.rootAffected;
2377
- const newNames = /* @__PURE__ */ new Set();
2378
- for (const surface of plan.newSurfaces) {
2379
- newNames.add(surface.name);
2380
- const measurement = measure?.(surface.instance) ?? null;
2381
- if (surface.phase === "enter") {
2382
- if (measurement !== null && !measurement.inViewport) {
2383
- surface.skipped = true;
2384
- continue;
2385
- }
2386
- applyViewTransitionSurface(viewTransitionHost, surface);
2387
- continue;
2388
- }
2389
- if (surface.phase === "update") {
2390
- const before = oldByName.get(surface.name)?.measurement ?? null;
2391
- if (before !== null && measurement !== null) {
2392
- const moved = before.x !== measurement.x || before.y !== measurement.y || before.width !== measurement.width || before.height !== measurement.height;
2393
- if (!before.inViewport && !measurement.inViewport || !surface.mustAnimate && !moved) {
2394
- surface.skipped = true;
2395
- viewTransitionHost.restore(surface.instance, surface.props);
2396
- if (oldByName.has(surface.name)) result.canceledNames.push(surface.name);
2397
- continue;
2398
- }
2399
- if ((before.width !== measurement.width || before.height !== measurement.height) && !measurement.absolutelyPositioned) rootAffected = true;
2400
- }
2401
- }
2402
- applyViewTransitionSurface(viewTransitionHost, surface);
2403
- }
2404
- for (const [name, surface] of oldByName) if (surface.phase === "update" && !newNames.has(name)) rootAffected = true;
2405
- result.cancelRootSnapshot = !rootAffected;
2406
- return result;
2407
- }
2408
- function applyViewTransitionSurface(viewTransitionHost, surface) {
2409
- viewTransitionHost.apply(surface.instance, surface.name, surface.className);
2410
- }
2411
- function restoreViewTransitionSurfaces(plan) {
2412
- if (viewTransitionHost === null) return;
2413
- const propsByInstance = /* @__PURE__ */ new Map();
2414
- for (const surface of plan.oldSurfaces) propsByInstance.set(surface.instance, surface.props);
2415
- for (const surface of plan.newSurfaces) propsByInstance.set(surface.instance, surface.props);
2416
- for (const [instance, props] of propsByInstance) viewTransitionHost.restore(instance, props);
2417
- }
2418
1786
  function commitRoot(root, finishedWork) {
2419
- if (!root.pendingViewTransitionCommit && isViewTransitionEligibleCommit(root) && viewTransitionHost?.suspend?.(root.container, () => scheduleRoot(root)) === true) {
2420
- root.parkedViewTransitionCommit = true;
2421
- root.callback = null;
2422
- root.callbackPriority = 0;
1787
+ if (!root.pendingCoordinatedCommit && commitCoordinator?.suspend?.(root, () => scheduleRoot(root)) === true) {
1788
+ parkCoordinatedCommit(root);
2423
1789
  return true;
2424
1790
  }
2425
1791
  commitDepth += 1;
@@ -2432,20 +1798,20 @@ function createRenderer(host) {
2432
1798
  commitLiveHookInstances(root);
2433
1799
  if (hasHiddenBoundaries) armRevealedHiddenBoundaries(finishedWork.child);
2434
1800
  commitEffects(root, finishedWork.child, 2);
2435
- const viewTransitionPlan = prepareViewTransitionPlan(root, finishedWork);
2436
1801
  const commitHostChanges = () => {
2437
- if (root.clearContainerBeforeCommit) {
2438
- requireHydrationHostConfig().clearContainer(root.container);
2439
- root.clearContainerBeforeCommit = false;
2440
- }
1802
+ const recoveringHydration = root.clearContainerBeforeCommit;
1803
+ if (recoveringHydration) requireHydrationHostConfig().clearContainer(root.container);
2441
1804
  if (root.needsCommitDeletions) {
2442
1805
  commitDeletions(root);
2443
1806
  root.needsCommitDeletions = false;
2444
1807
  }
1808
+ if (!recoveringHydration) commitAssetResourceUpdates(root);
2445
1809
  commitDataDependencies(root);
2446
1810
  commitHostUpdates(root);
2447
1811
  commitMutationEffects(finishedWork.child);
2448
1812
  if (hasHiddenBoundaries) commitHiddenBoundaryVisibility(finishedWork.child);
1813
+ if (recoveringHydration) commitAssetResourceUpdates(root);
1814
+ root.clearContainerBeforeCommit = false;
2449
1815
  };
2450
1816
  const completeCommit = () => {
2451
1817
  hasHiddenBoundaries = hiddenStates.size > 0;
@@ -2453,10 +1819,10 @@ function createRenderer(host) {
2453
1819
  deactivateHydration(root);
2454
1820
  root.hydrationInitialElement = NoHydrationInitialElement;
2455
1821
  root.consumedPendingQueues = [];
2456
- markRootFinished(root, root.pendingLanes & ~root.renderLanes | finishedWork.lanes | finishedWork.childLanes);
1822
+ markRootCompleted(root, root.pendingLanes & ~root.renderLanes | finishedWork.lanes | finishedWork.childLanes);
2457
1823
  if (includesSomeLane(finishedWork.childLanes, 536870912)) {
2458
1824
  markRootPending(root, OffscreenLane);
2459
- root.suspendedLanes &= -536870913;
1825
+ root.suspendedLanes &= ~OffscreenLane;
2460
1826
  }
2461
1827
  try {
2462
1828
  commitExternalStores(root);
@@ -2473,56 +1839,76 @@ function createRenderer(host) {
2473
1839
  flushRecoverableErrors(root);
2474
1840
  requestPaint();
2475
1841
  };
2476
- const commitWithoutViewTransition = () => {
2477
- commitHostChanges();
2478
- completeCommit();
1842
+ const finishDeferredCommit = () => {
1843
+ if (!root.pendingCoordinatedCommit) return;
1844
+ root.pendingCoordinatedCommit = false;
1845
+ finishRootWork(root);
1846
+ flushPostCommitSyncWork();
2479
1847
  };
2480
- const commitWithViewTransition = () => {
2481
- const isDeferredCommit = root.pendingViewTransitionCommit;
2482
- if (isDeferredCommit) commitDepth += 1;
2483
- try {
2484
- commitHostChanges();
2485
- const resolution = resolveViewTransitionPlan(viewTransitionPlan);
2486
- completeCommit();
2487
- return resolution;
2488
- } catch (error) {
2489
- if (!isDeferredCommit) throw error;
2490
- const info = root.uncaughtErrorInfo ?? errorInfoFor(root.current, error);
2491
- restartRootWork(root);
2492
- clearRootAfterUncaughtError(root);
2493
- reportUncaughtError(root, error, info);
2494
- if (root.onUncaughtError === null) setTimeout(() => {
2495
- throw error;
2496
- });
2497
- return {
2498
- canceledNames: [],
2499
- cancelRootSnapshot: false
2500
- };
2501
- } finally {
2502
- if (isDeferredCommit) {
2503
- root.pendingViewTransitionCommit = false;
2504
- commitDepth -= 1;
2505
- finishRootWork(root);
2506
- flushPostCommitSyncWork();
1848
+ if (commitCoordinator !== null) {
1849
+ let didRunMutation = false;
1850
+ let didFinishCapture = false;
1851
+ const context = {
1852
+ container: root.container,
1853
+ finishedWork,
1854
+ priority: commitPriority(root.renderLanes),
1855
+ root,
1856
+ captureFinished() {
1857
+ if (!didRunMutation) throw new Error("A commit coordinator cannot finish capture before running the mutation transaction.");
1858
+ didFinishCapture = true;
1859
+ finishDeferredCommit();
1860
+ },
1861
+ runMutation(afterMutation) {
1862
+ if (didRunMutation) throw new Error("A commit coordinator may run its mutation transaction only once.");
1863
+ didRunMutation = true;
1864
+ const isDeferredCommit = root.pendingCoordinatedCommit;
1865
+ if (isDeferredCommit) commitDepth += 1;
1866
+ try {
1867
+ commitHostChanges();
1868
+ completeCommit();
1869
+ return afterMutation();
1870
+ } catch (error) {
1871
+ if (!isDeferredCommit) throw error;
1872
+ const info = root.uncaughtErrorInfo ?? errorInfoFor(root.current, error);
1873
+ restartRootWork(root);
1874
+ clearRootAfterUncaughtError(root);
1875
+ reportUncaughtError(root, error, info);
1876
+ if (root.onUncaughtError === null) setTimeout(() => {
1877
+ throw error;
1878
+ });
1879
+ return;
1880
+ } finally {
1881
+ if (isDeferredCommit) commitDepth -= 1;
1882
+ }
2507
1883
  }
1884
+ };
1885
+ switch (commitCoordinator.commit(context)) {
1886
+ case false:
1887
+ if (didRunMutation) throw new Error("A commit coordinator returned false after running the mutation transaction.");
1888
+ break;
1889
+ case "committed":
1890
+ if (!didRunMutation) throw new Error("A commit coordinator returned \"committed\" without running the mutation transaction.");
1891
+ return false;
1892
+ case "deferred":
1893
+ root.pendingCoordinatedCommit = true;
1894
+ root.callback = null;
1895
+ root.callbackPriority = 0;
1896
+ if (didFinishCapture) finishDeferredCommit();
1897
+ return true;
2508
1898
  }
2509
- };
2510
- if (viewTransitionPlan !== null && viewTransitionHost !== null) {
2511
- const viewTransitionResult = viewTransitionHost.commit(root.container, () => applyOldViewTransitionSurfaces(viewTransitionPlan), commitWithViewTransition, () => restoreViewTransitionSurfaces(viewTransitionPlan));
2512
- if (viewTransitionResult === "deferred") {
2513
- root.pendingViewTransitionCommit = true;
2514
- root.callback = null;
2515
- root.callbackPriority = 0;
2516
- return true;
2517
- }
2518
- if (viewTransitionResult === "committed") return false;
2519
1899
  }
2520
- commitWithoutViewTransition();
1900
+ commitHostChanges();
1901
+ completeCommit();
2521
1902
  return false;
2522
1903
  } finally {
2523
1904
  commitDepth -= 1;
2524
1905
  }
2525
1906
  }
1907
+ function parkCoordinatedCommit(root) {
1908
+ root.parkedCoordinatedCommit = true;
1909
+ root.callback = null;
1910
+ root.callbackPriority = 0;
1911
+ }
2526
1912
  function scheduleDehydratedSuspenseRetries(root) {
2527
1913
  if (!root.isHydrationRoot && root.dehydratedSuspenseCount === 0 && !root.needsRootHydrationCompletion) {
2528
1914
  root.dehydratedBoundaries = /* @__PURE__ */ new Map();
@@ -2614,6 +2000,7 @@ function createRenderer(host) {
2614
2000
  }
2615
2001
  if (host.clearContainer !== void 0) {
2616
2002
  removePortalDescendants(root.current.child);
2003
+ releaseOutOfBandDescendants(root.current.child);
2617
2004
  host.clearContainer(root.container);
2618
2005
  } else if (root.current.child !== null) {
2619
2006
  let child = root.current.child;
@@ -2634,7 +2021,7 @@ function createRenderer(host) {
2634
2021
  root.commitEffectPhases = 0;
2635
2022
  root.needsCommitDeletions = false;
2636
2023
  root.committedCaughtErrors.length = 0;
2637
- markRootFinished(root, 0);
2024
+ markRootCompleted(root, 0);
2638
2025
  pendingRoots.delete(root);
2639
2026
  }
2640
2027
  function commitMutationEffects(node, hidden = false) {
@@ -2745,6 +2132,25 @@ function createRenderer(host) {
2745
2132
  }
2746
2133
  function insertHostSubtree(node, parent, before) {
2747
2134
  visitHostNodes(node, (child) => host.insertBefore(parent, child, before));
2135
+ visitHostFibers(node, (child) => {
2136
+ if (child.committedProps !== null) return;
2137
+ if (child.tag === 1 && isHoistedFiber(child)) {
2138
+ acquireHoistedInstance(child);
2139
+ markHostCommitted(child);
2140
+ markHostSubtreeCommitted(child.child);
2141
+ return;
2142
+ }
2143
+ markHostCommitted(child);
2144
+ if (isPreassembledHostSubtree(child)) markHostSubtreeCommitted(child.child);
2145
+ });
2146
+ }
2147
+ function visitHostFibers(node, visitor) {
2148
+ if (isHost(node)) {
2149
+ visitor(node);
2150
+ return;
2151
+ }
2152
+ if (node.tag === 8) return;
2153
+ for (let child = node.child; child !== null; child = child.sibling) visitHostFibers(child, visitor);
2748
2154
  }
2749
2155
  function insertPortalChildren(node) {
2750
2156
  const parent = portalTarget(node);
@@ -2765,18 +2171,12 @@ function createRenderer(host) {
2765
2171
  const hoistedHost = requireHoistedAssetHostConfig();
2766
2172
  const previousProps = previousCommittedProps(node);
2767
2173
  const instance = node.stateNode;
2768
- const next = hoistedHost.updateHoistedInstance(instance, previousProps, node.props) ?? instance;
2769
- if (next !== instance) {
2770
- adoptSwappedHoistedInstance(node, next);
2771
- return;
2772
- }
2773
- if ((node.flags & 8) !== 0) commitHostTextContent(node, previousProps);
2174
+ const next = hoistedHost.updateHoistedInstance(instance, previousProps, node.props, assetResourceOwner(node)) ?? instance;
2175
+ if (next !== instance) adoptSwappedHoistedInstance(node, next);
2774
2176
  }
2775
2177
  function adoptSwappedHoistedInstance(node, next) {
2776
2178
  node.stateNode = next;
2777
2179
  if (node.alternate !== null) node.alternate.stateNode = next;
2778
- const text = hostTextContent(node.props.children);
2779
- if (text !== null) host.setTextContent?.(next, text);
2780
2180
  }
2781
2181
  function commitHydratedSuspenseBoundary(node) {
2782
2182
  const boundary = dehydratedSuspenseBoundary(node.alternate);
@@ -2786,7 +2186,7 @@ function createRenderer(host) {
2786
2186
  function commitHydratedActivityBoundary(node) {
2787
2187
  const state = fiberActivityState(node);
2788
2188
  if (state?.dehydrated == null) return;
2789
- requireActivityHydrationHostConfig().commitHydratedActivityBoundary(state.dehydrated);
2189
+ requireActivityHydrationHostConfig().commitHydratedActivityBoundary(state.dehydrated.boundary);
2790
2190
  state.dehydrated = null;
2791
2191
  }
2792
2192
  function commitHostTextContent(node, previousProps) {
@@ -2812,7 +2212,7 @@ function createRenderer(host) {
2812
2212
  function acquireHoistedInstance(node) {
2813
2213
  const hoistedHost = requireHoistedAssetHostConfig();
2814
2214
  const instance = node.stateNode;
2815
- const resolved = hoistedHost.commitHoistedInstance(instance) ?? instance;
2215
+ const resolved = hoistedHost.commitHoistedInstance(instance, node.props, assetResourceOwner(node)) ?? instance;
2816
2216
  if (resolved === instance) return;
2817
2217
  adoptSwappedHoistedInstance(node, resolved);
2818
2218
  }
@@ -2851,6 +2251,23 @@ function createRenderer(host) {
2851
2251
  if (cursor.alternate !== null) cursor.alternate.dataDependenciesDirty = false;
2852
2252
  }
2853
2253
  }
2254
+ function commitAssetResourceUpdates(root) {
2255
+ if (host.commitAssetResources === void 0) return;
2256
+ for (const cursor of root.commitIndex) {
2257
+ if ((cursor.flags & 16384) === 0) continue;
2258
+ commitHostMutation(cursor, () => host.commitAssetResources?.(cursor.committedProps?.assets ?? null, cursor.props.assets, assetResourceOwner(cursor)));
2259
+ cursor.committedProps = cursor.props;
2260
+ if (cursor.alternate !== null) cursor.alternate.committedProps = cursor.props;
2261
+ cursor.flags &= ~AssetFlag;
2262
+ }
2263
+ }
2264
+ function assertPlacedHostCommitParity(node, placed) {
2265
+ for (let child = node; child !== null; child = child.sibling) {
2266
+ const childPlaced = placed || (child.flags & 1) !== 0;
2267
+ if (childPlaced && isHost(child) && child.committedProps === null) throw new Error("Fig internal parity error: a placed host fiber has no committed props after the mutation phase (a subtree insertion skipped commit marking).");
2268
+ if (childPlaced || (child.subtreeFlags & 1) !== 0) assertPlacedHostCommitParity(child.child, childPlaced);
2269
+ }
2270
+ }
2854
2271
  function deleteFiberDataTree(node) {
2855
2272
  const store = rootOf(node).dataStore;
2856
2273
  walkFiberForest(node, (cursor) => {
@@ -2864,7 +2281,7 @@ function createRenderer(host) {
2864
2281
  if (state !== null) hiddenStates.delete(state);
2865
2282
  }
2866
2283
  function dehydratedActivityBoundary(node) {
2867
- return node.tag === 10 ? fiberActivityState(node)?.dehydrated ?? null : null;
2284
+ return node.tag === 10 ? fiberActivityState(node)?.dehydrated?.boundary ?? null : null;
2868
2285
  }
2869
2286
  function remove(node, parent) {
2870
2287
  const dehydratedActivity = dehydratedActivityBoundary(node);
@@ -2882,29 +2299,37 @@ function createRenderer(host) {
2882
2299
  host.removePortalContainer?.(portalTarget(node));
2883
2300
  return;
2884
2301
  }
2302
+ if (node.tag === 9) releaseAssetResources(node);
2885
2303
  if (node.tag === 1 && isHoistedFiber(node)) {
2886
- if (node.committedProps !== null) requireHoistedAssetHostConfig().removeHoistedInstance(node.stateNode);
2304
+ if (node.committedProps !== null) requireHoistedAssetHostConfig().removeHoistedInstance(node.stateNode, assetResourceOwner(node));
2887
2305
  return;
2888
2306
  }
2889
2307
  if (isHost(node)) {
2890
2308
  removePortalDescendants(node.child);
2891
- removeHoistedDescendants(node.child);
2309
+ releaseOutOfBandDescendants(node.child);
2892
2310
  host.removeChild(parent, hostNode(node));
2893
2311
  return;
2894
2312
  }
2895
2313
  for (let child = node.child; child !== null; child = child.sibling) remove(child, parent);
2896
2314
  }
2897
- function removeHoistedDescendants(node) {
2898
- if (host.isHoistedInstance === void 0) return;
2315
+ function releaseOutOfBandDescendants(node) {
2316
+ if (host.resolveHoistedInstance === void 0 && host.commitAssetResources === void 0) return;
2899
2317
  for (let child = node; child !== null; child = child.sibling) {
2900
2318
  if (child.tag === 8) continue;
2319
+ if (child.tag === 9) releaseAssetResources(child);
2901
2320
  if (child.tag === 1 && isHoistedFiber(child)) {
2902
- if (child.committedProps !== null && child.stateNode !== null) requireHoistedAssetHostConfig().removeHoistedInstance(child.stateNode);
2321
+ if (child.committedProps !== null && child.stateNode !== null) requireHoistedAssetHostConfig().removeHoistedInstance(child.stateNode, assetResourceOwner(child));
2903
2322
  continue;
2904
2323
  }
2905
- removeHoistedDescendants(child.child);
2324
+ releaseOutOfBandDescendants(child.child);
2906
2325
  }
2907
2326
  }
2327
+ function releaseAssetResources(node) {
2328
+ if (node.tag !== 9 || node.committedProps === null || host.commitAssetResources === void 0) return;
2329
+ host.commitAssetResources(node.committedProps.assets, null, assetResourceOwner(node));
2330
+ node.committedProps = null;
2331
+ if (node.alternate !== null) node.alternate.committedProps = null;
2332
+ }
2908
2333
  function removePortalChildren(node) {
2909
2334
  const parent = portalTarget(node);
2910
2335
  for (let child = node.child; child !== null; child = child.sibling) remove(child, parent);
@@ -2929,6 +2354,7 @@ function createRenderer(host) {
2929
2354
  throw new Error("Could not find a host parent for fiber.");
2930
2355
  }
2931
2356
  function hostSibling(node) {
2357
+ if (rootOf(node).clearContainerBeforeCommit) return null;
2932
2358
  const dehydratedBoundary = dehydratedSuspenseParent(node);
2933
2359
  if (dehydratedBoundary !== null) return dehydratedBoundary.start;
2934
2360
  let cursor = node;
@@ -3173,13 +2599,14 @@ function createRenderer(host) {
3173
2599
  next.props = props;
3174
2600
  next.memoizedProps = current.memoizedProps;
3175
2601
  next.committedProps = current.committedProps;
2602
+ next.assetResourceOwner = current.assetResourceOwner;
3176
2603
  next.memoizedState = current.memoizedState;
3177
2604
  next.stateNode = current.stateNode;
3178
2605
  next.return = current.return;
3179
2606
  next.child = null;
3180
2607
  next.sibling = null;
3181
2608
  next.index = current.index;
3182
- next.flags = 0;
2609
+ next.flags = current.flags & HoistedStaticFlag;
3183
2610
  next.subtreeFlags = 0;
3184
2611
  next.deletions = null;
3185
2612
  next.lanes = current.lanes;
@@ -3214,8 +2641,9 @@ function createRenderer(host) {
3214
2641
  function fiberFrom(child) {
3215
2642
  if (typeof child === "string") return fiber(2, null, null, { nodeValue: child }, null);
3216
2643
  if (isPortal(child)) return fiber(8, null, child.key, portalProps(child), null);
3217
- if (!isValidElement(child)) return null;
3218
- return fiber(tagFor(child), child.type, child.key, child.props, null);
2644
+ if (isValidElement(child)) return fiber(tagFor(child), child.type, child.key, child.props, null);
2645
+ if (isThenable(child)) return fiber(12, null, null, { thenable: child }, null);
2646
+ return null;
3219
2647
  }
3220
2648
  function portalTarget(node) {
3221
2649
  return node.props.target;
@@ -3244,10 +2672,17 @@ function createRenderer(host) {
3244
2672
  contextDependencies: null,
3245
2673
  contextSubtreeDependencies: null,
3246
2674
  dataDependenciesDirty: false,
2675
+ assetResourceOwner: null,
3247
2676
  boundaryState: null,
3248
2677
  hiddenState: null
3249
2678
  };
3250
2679
  }
2680
+ function assetResourceOwner(node) {
2681
+ const owner = node.assetResourceOwner ?? node.alternate?.assetResourceOwner ?? {};
2682
+ node.assetResourceOwner = owner;
2683
+ if (node.alternate !== null) node.alternate.assetResourceOwner = owner;
2684
+ return owner;
2685
+ }
3251
2686
  function rootOf(node) {
3252
2687
  const root = rootOfOrNull(node);
3253
2688
  if (root === null) throw new Error("Could not find a root for fiber.");
@@ -3299,6 +2734,7 @@ function createRenderer(host) {
3299
2734
  hydrateRoot,
3300
2735
  hydrateTarget,
3301
2736
  flushSync,
2737
+ installCommitCoordinator,
3302
2738
  scheduleRefresh
3303
2739
  };
3304
2740
  function scheduleRefresh(update) {}
@@ -3309,10 +2745,7 @@ function createRenderer(host) {
3309
2745
  return findDehydratedSuspenseBoundaryForTarget(node.child, target) ?? findDehydratedSuspenseBoundaryForTarget(node.sibling, target);
3310
2746
  }
3311
2747
  function isHiddenBoundary(node) {
3312
- return isHiddenBoundaryTag(node) && activityHidden(node.props);
3313
- }
3314
- function isHiddenBoundaryTag(node) {
3315
- return node.tag === 10;
2748
+ return node.tag === 10 && activityHidden(node.props);
3316
2749
  }
3317
2750
  function requireActivityHostConfig() {
3318
2751
  if (activityHostConfig !== null) return activityHostConfig;
@@ -3325,7 +2758,7 @@ function createRenderer(host) {
3325
2758
  if ((cursor.flags & 16) !== 0) continue;
3326
2759
  const subtreeVisibility = (cursor.subtreeFlags & 32) !== 0;
3327
2760
  if ((cursor.flags & 32) === 0 && !subtreeVisibility) continue;
3328
- const boundary = isHiddenBoundaryTag(cursor);
2761
+ const boundary = cursor.tag === 10;
3329
2762
  const boundaryHidden = boundary && activityHidden(cursor.props);
3330
2763
  if (boundary && (cursor.flags & 32) !== 0) {
3331
2764
  const effectiveHidden = hidden || boundaryHidden;
@@ -3340,7 +2773,7 @@ function createRenderer(host) {
3340
2773
  if (!effectiveHidden && includesSomeLane(cursor.childLanes, 536870912)) {
3341
2774
  const root = rootOf(cursor);
3342
2775
  markRootPending(root, 32);
3343
- markRootEntangled(root, 536870944);
2776
+ markRootEntangled(root, 32 | OffscreenLane);
3344
2777
  scheduleOrBatchRoot(root);
3345
2778
  }
3346
2779
  }
@@ -3373,7 +2806,7 @@ function createRenderer(host) {
3373
2806
  if ((cursor.flags & 16) !== 0) continue;
3374
2807
  const subtreeVisibility = (cursor.subtreeFlags & 32) !== 0;
3375
2808
  if ((cursor.flags & 32) === 0 && !subtreeVisibility) continue;
3376
- if (isHiddenBoundaryTag(cursor) && (cursor.flags & 32) !== 0 && !activityHidden(cursor.props) && cursor.child !== null) armDeferredEffects(cursor.child);
2809
+ if (cursor.tag === 10 && (cursor.flags & 32) !== 0 && !activityHidden(cursor.props) && cursor.child !== null) armDeferredEffects(cursor.child);
3377
2810
  if (subtreeVisibility) armRevealedHiddenBoundaries(cursor.child);
3378
2811
  }
3379
2812
  }
@@ -3490,7 +2923,7 @@ function createRenderer(host) {
3490
2923
  if (subtreeFlags !== 0) clearHiddenSubtreeFlags(cursor.child);
3491
2924
  return false;
3492
2925
  }
3493
- return (subtreeFlags & -4097) !== 0;
2926
+ return (subtreeFlags & ~StaticFlagsMask) !== 0;
3494
2927
  });
3495
2928
  }
3496
2929
  function clearHiddenSubtreeFlags(node) {
@@ -3498,7 +2931,7 @@ function createRenderer(host) {
3498
2931
  const adopted = (cursor.flags & 16) !== 0;
3499
2932
  const subtreeFlags = cursor.subtreeFlags;
3500
2933
  clearTransientFlags(cursor);
3501
- return !adopted && (subtreeFlags & -4097) !== 0;
2934
+ return !adopted && (subtreeFlags & -12289) !== 0;
3502
2935
  });
3503
2936
  }
3504
2937
  function scheduleReactiveEffects(root) {
@@ -3650,6 +3083,7 @@ function createActionState(action, value) {
3650
3083
  action,
3651
3084
  controller: null,
3652
3085
  generation: 0,
3086
+ runner: null,
3653
3087
  value
3654
3088
  },
3655
3089
  pending: 0,
@@ -3662,13 +3096,14 @@ function resolveInitialState(initialState) {
3662
3096
  function sameType(fiber, child) {
3663
3097
  if (typeof child === "string") return fiber.tag === 2;
3664
3098
  if (isPortal(child)) return fiber.tag === 8 && fiber.props.target === child.target;
3665
- if (!isValidElement(child)) return false;
3666
- return fiber.type === child.type;
3099
+ if (isValidElement(child)) return fiber.type === child.type;
3100
+ return isThenable(child) && fiber.tag === 12;
3667
3101
  }
3668
3102
  function propsFor(child) {
3669
3103
  if (typeof child === "string") return { nodeValue: child };
3670
3104
  if (isPortal(child)) return portalProps(child);
3671
3105
  if (isValidElement(child)) return child.props;
3106
+ if (isThenable(child)) return { thenable: child };
3672
3107
  throw invalidChildError(child);
3673
3108
  }
3674
3109
  function portalProps(child) {
@@ -3714,6 +3149,6 @@ function suspenseRetryLane(lanes) {
3714
3149
  return retryLanes === 0 ? claimNextRetryLane() : getHighestPriorityLane(retryLanes);
3715
3150
  }
3716
3151
  //#endregion
3717
- export { act, createRenderer, runWithEventPriority };
3152
+ export { createRenderer, runWithEventPriority };
3718
3153
 
3719
3154
  //# sourceMappingURL=index.js.map