@absolutejs/absolute 0.19.0-beta.747 → 0.19.0-beta.748
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/angular/browser.js +35 -1
- package/dist/angular/browser.js.map +5 -4
- package/dist/angular/index.js +35 -1
- package/dist/angular/index.js.map +5 -4
- package/dist/dev/client/handlers/angular.ts +47 -0
- package/dist/src/angular/browser.d.ts +1 -0
- package/dist/src/angular/index.d.ts +1 -0
- package/dist/src/angular/preserveAcrossHmr.d.ts +7 -0
- package/package.json +1 -1
|
@@ -679,6 +679,13 @@ const handleFullUpdate = async (message: HMRMessage) => {
|
|
|
679
679
|
if (!indexPath) return;
|
|
680
680
|
|
|
681
681
|
const doUpdate = async () => {
|
|
682
|
+
// Snapshot every instance that opted into `preserveAcrossHmr(this)`
|
|
683
|
+
// before destroying the app. The new instances created during
|
|
684
|
+
// bootstrap will read these values back via the same helper, so
|
|
685
|
+
// service state (auth tokens, cached data, subscriptions held by
|
|
686
|
+
// reference) survives a full re-bootstrap. Generic by class name
|
|
687
|
+
// — no per-app configuration here.
|
|
688
|
+
captureHmrPreservedInstanceStates();
|
|
682
689
|
destroyAngularApp();
|
|
683
690
|
await bootstrapAngularModule(indexPath, rootSelector, rootContainer);
|
|
684
691
|
restoreComponentState(componentState);
|
|
@@ -689,3 +696,43 @@ const handleFullUpdate = async (message: HMRMessage) => {
|
|
|
689
696
|
|
|
690
697
|
await runWithViewTransition(doUpdate);
|
|
691
698
|
};
|
|
699
|
+
|
|
700
|
+
/* Snapshot every WeakRef-tracked instance's enumerable own properties
|
|
701
|
+
into the shared cache. The runtime helper `preserveAcrossHmr(this)`
|
|
702
|
+
from `@absolutejs/absolute/angular` populates the tracker, and on the
|
|
703
|
+
constructor of the next-bootstrapped instance reads back from the
|
|
704
|
+
cache. We talk to the same `globalThis`-anchored Map/Set as that
|
|
705
|
+
helper rather than importing it directly so this dev-client bundle
|
|
706
|
+
doesn't pull in the Angular runtime. */
|
|
707
|
+
type HmrPreserveScope = typeof globalThis & {
|
|
708
|
+
__ABS_HMR_INSTANCE_STATE__?: Map<string, Record<string, unknown>>;
|
|
709
|
+
__ABS_HMR_TRACKED_INSTANCES__?: Set<WeakRef<object>>;
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
const captureHmrPreservedInstanceStates = () => {
|
|
713
|
+
const scope = globalThis as HmrPreserveScope;
|
|
714
|
+
const tracker = scope.__ABS_HMR_TRACKED_INSTANCES__;
|
|
715
|
+
if (!tracker || tracker.size === 0) return;
|
|
716
|
+
|
|
717
|
+
const cache = (scope.__ABS_HMR_INSTANCE_STATE__ ??= new Map());
|
|
718
|
+
const dead: WeakRef<object>[] = [];
|
|
719
|
+
|
|
720
|
+
for (const ref of tracker) {
|
|
721
|
+
const instance = ref.deref();
|
|
722
|
+
if (!instance) {
|
|
723
|
+
dead.push(ref);
|
|
724
|
+
continue;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
const key = instance.constructor?.name;
|
|
728
|
+
if (!key || key === 'Object') continue;
|
|
729
|
+
|
|
730
|
+
const props: Record<string, unknown> = {};
|
|
731
|
+
for (const prop of Object.keys(instance)) {
|
|
732
|
+
props[prop] = (instance as Record<string, unknown>)[prop];
|
|
733
|
+
}
|
|
734
|
+
cache.set(key, props);
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
dead.forEach((ref) => tracker.delete(ref));
|
|
738
|
+
};
|
|
@@ -2,6 +2,7 @@ export type { AngularPageDefinition, AngularPagePropsOf } from '../../types/angu
|
|
|
2
2
|
export { ABSOLUTE_HTTP_TRANSFER_CACHE_SKIP_HEADER, buildAbsoluteHttpTransferCacheOptions } from './httpTransferCache';
|
|
3
3
|
export { createDeterministicRandom, DETERMINISTIC_NOW, DETERMINISTIC_RANDOM, DETERMINISTIC_SEED, provideDeterministicEnv } from './deterministicEnv';
|
|
4
4
|
export { defineAngularPage } from './page';
|
|
5
|
+
export { preserveAcrossHmr } from './preserveAcrossHmr';
|
|
5
6
|
export { Island } from './Island.browser';
|
|
6
7
|
export { withPendingTask } from './pendingTask';
|
|
7
8
|
export { REQUEST, REQUEST_CONTEXT, RESPONSE_INIT } from './requestProviders';
|
|
@@ -4,6 +4,7 @@ export { ABSOLUTE_HTTP_TRANSFER_CACHE_SKIP_HEADER, buildAbsoluteHttpTransferCach
|
|
|
4
4
|
export { createDeterministicRandom, DETERMINISTIC_NOW, DETERMINISTIC_RANDOM, DETERMINISTIC_SEED, provideDeterministicEnv } from './deterministicEnv';
|
|
5
5
|
export { handleAngularPageRequest } from './pageHandler';
|
|
6
6
|
export { defineAngularPage } from './page';
|
|
7
|
+
export { preserveAcrossHmr } from './preserveAcrossHmr';
|
|
7
8
|
export { withPendingTask } from './pendingTask';
|
|
8
9
|
export { REQUEST, REQUEST_CONTEXT, RESPONSE_INIT } from './requestProviders';
|
|
9
10
|
export { createTypedIsland } from './createIsland';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Mark a service instance for state preservation across full Angular HMR
|
|
2
|
+
* re-bootstraps. Call once from the constructor. Safe in production
|
|
3
|
+
* (no-op outside dev mode). */
|
|
4
|
+
export declare const preserveAcrossHmr: (instance: object) => void;
|
|
5
|
+
/** Snapshot every tracked instance's enumerable own properties into the
|
|
6
|
+
* cache. Called by the HMR client right before `destroyAngularApp()`. */
|
|
7
|
+
export declare const captureTrackedInstanceStates: () => void;
|
package/package.json
CHANGED