@absolutejs/absolute 0.19.0-beta.745 → 0.19.0-beta.746
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.
|
@@ -511,12 +511,27 @@ const tickAngularApp = () => {
|
|
|
511
511
|
}
|
|
512
512
|
};
|
|
513
513
|
|
|
514
|
-
|
|
514
|
+
/* HMR updates must be serialized.
|
|
515
|
+
If a second `startViewTransition` runs while a previous one is still in
|
|
516
|
+
flight, the browser aborts the old transition — but the old update
|
|
517
|
+
callback (destroyApp + async bootstrap) keeps running. Two updateFns
|
|
518
|
+
then race over the DOM and Angular state, corrupting HMR and forcing a
|
|
519
|
+
page refresh.
|
|
520
|
+
We avoid that by queuing later updates until the current one finishes.
|
|
521
|
+
If multiple updates queue up, only the latest matters (intermediate ones
|
|
522
|
+
are superseded), so we collapse to a single pending entry. */
|
|
523
|
+
let activeUpdate: Promise<void> | null = null;
|
|
524
|
+
let pendingUpdate: (() => Promise<void>) | null = null;
|
|
525
|
+
|
|
526
|
+
const runOneUpdate = async (updateFn: () => Promise<void>) => {
|
|
515
527
|
const doc: ViewTransitionDocument = document;
|
|
528
|
+
|
|
516
529
|
if (typeof doc.startViewTransition !== 'function') {
|
|
517
|
-
|
|
530
|
+
try {
|
|
531
|
+
await updateFn();
|
|
532
|
+
} catch (err) {
|
|
518
533
|
console.warn('[HMR] Angular update failed (non-fatal):', err);
|
|
519
|
-
}
|
|
534
|
+
}
|
|
520
535
|
|
|
521
536
|
return;
|
|
522
537
|
}
|
|
@@ -531,15 +546,56 @@ const runWithViewTransition = (updateFn: () => Promise<void>) => {
|
|
|
531
546
|
/* ignored */
|
|
532
547
|
}
|
|
533
548
|
|
|
534
|
-
|
|
549
|
+
let updatePromise: Promise<void> = Promise.resolve();
|
|
550
|
+
try {
|
|
551
|
+
const transition = doc.startViewTransition(() => {
|
|
552
|
+
updatePromise = updateFn();
|
|
553
|
+
|
|
554
|
+
return updatePromise;
|
|
555
|
+
});
|
|
556
|
+
// Wait for both the visual transition and the update callback.
|
|
557
|
+
// `transition.finished` rejects with AbortError when a new transition
|
|
558
|
+
// supersedes this one — swallow that since we serialize updates so
|
|
559
|
+
// it shouldn't happen, and even if it does we still want to wait
|
|
560
|
+
// for `updateFn` to complete before releasing the next update.
|
|
561
|
+
await Promise.all([
|
|
562
|
+
transition.finished.catch(() => {
|
|
563
|
+
/* skipped */
|
|
564
|
+
}),
|
|
565
|
+
updatePromise.catch((err) => {
|
|
566
|
+
console.warn('[HMR] Angular update failed (non-fatal):', err);
|
|
567
|
+
})
|
|
568
|
+
]);
|
|
569
|
+
} catch (err) {
|
|
570
|
+
console.warn('[HMR] Angular update failed (non-fatal):', err);
|
|
571
|
+
// If startViewTransition itself threw, run the update directly so
|
|
572
|
+
// HMR still applies (loses the crossfade but preserves correctness).
|
|
573
|
+
try {
|
|
574
|
+
await updateFn();
|
|
575
|
+
} catch (innerErr) {
|
|
576
|
+
console.warn('[HMR] Angular update failed (non-fatal):', innerErr);
|
|
577
|
+
}
|
|
578
|
+
} finally {
|
|
535
579
|
if (styleEl && styleEl.parentNode) styleEl.remove();
|
|
536
|
-
}
|
|
580
|
+
}
|
|
581
|
+
};
|
|
537
582
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
583
|
+
const runWithViewTransition = (updateFn: () => Promise<void>) => {
|
|
584
|
+
if (activeUpdate) {
|
|
585
|
+
// Supersede any earlier queued update — only the latest matters.
|
|
586
|
+
pendingUpdate = updateFn;
|
|
587
|
+
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
activeUpdate = runOneUpdate(updateFn).finally(() => {
|
|
592
|
+
activeUpdate = null;
|
|
593
|
+
if (pendingUpdate) {
|
|
594
|
+
const next = pendingUpdate;
|
|
595
|
+
pendingUpdate = null;
|
|
596
|
+
runWithViewTransition(next);
|
|
597
|
+
}
|
|
598
|
+
});
|
|
543
599
|
};
|
|
544
600
|
|
|
545
601
|
const handleFullUpdate = (message: HMRMessage) => {
|
package/package.json
CHANGED