@absolutejs/absolute 0.19.0-beta.867 → 0.19.0-beta.868

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.
@@ -13,7 +13,9 @@ import type {} from '../../../types/globals';
13
13
  * shim setup synchronous + at module scope so it's installed during
14
14
  * `hmrClient.ts`'s import-evaluation pass, before page chunks load. */
15
15
 
16
- export type AngularHmrEvent = 'angular:component-update';
16
+ export type AngularHmrEvent =
17
+ | 'angular:component-update'
18
+ | 'angular:component-remount';
17
19
  export type AngularComponentUpdate = {
18
20
  id: string;
19
21
  timestamp: number;
@@ -75,3 +77,9 @@ export const dispatchAngularComponentUpdate = (
75
77
  ) => {
76
78
  globalThis.__angularHmr?.dispatch('angular:component-update', data);
77
79
  };
80
+
81
+ export const dispatchAngularComponentRemount = (
82
+ data: AngularComponentUpdate
83
+ ) => {
84
+ globalThis.__angularHmr?.dispatch('angular:component-remount', data);
85
+ };
@@ -0,0 +1,267 @@
1
+ import type {} from '../../../types/globals';
2
+ /* Per-component Tier 1 remount.
3
+ *
4
+ * When fastHmr reports a structural change for a component class,
5
+ * full app rebootstrap loses all sibling component state. Instead, we
6
+ * remount only the affected components: destroy each live instance +
7
+ * recreate at the same DOM host with the new factory.
8
+ *
9
+ * This uses public `createComponent` for the heavy lifting (it runs
10
+ * the new constructor, sets up DI, fires lifecycle hooks, renders the
11
+ * template, attaches change detection). We supplement with vendored
12
+ * LView slot manipulation to (a) find each live instance's parent
13
+ * LView slot and (b) splice the freshly-created LView into that slot
14
+ * so it participates in the parent's view tree instead of being a
15
+ * detached root.
16
+ *
17
+ * Caveats baked into this approach:
18
+ * • The new LView starts as a "root" view (createComponent attaches
19
+ * it to ApplicationRef). After splice, it's a child of the
20
+ * original parent. We need to detach from ApplicationRef so it's
21
+ * not double-tracked.
22
+ * • Old @Input bindings from the parent are NOT re-applied. The
23
+ * parent's template flow runs at parent-CD time and wires inputs
24
+ * then; until then the new instance sees default values. In
25
+ * practice this matches Tier 1 rebootstrap behavior — no worse.
26
+ * • Old projection content (ng-content) doesn't transfer. If the
27
+ * parent injected a child via ng-content, the new instance has an
28
+ * empty projection slot until parent re-renders. Logged as a
29
+ * known limitation in ANGULAR_PER_COMPONENT_REMOUNT_RESEARCH.md. */
30
+
31
+ import {
32
+ CHILD_HEAD,
33
+ CHILD_TAIL,
34
+ CONTEXT,
35
+ HOST,
36
+ PARENT,
37
+ T_HOST,
38
+ TVIEW
39
+ } from '../../angular/vendor/lview/slotConstants';
40
+ import {
41
+ executeOnDestroys,
42
+ isLView,
43
+ markLViewDestroyed,
44
+ processCleanups,
45
+ replaceLViewInTree,
46
+ type LView,
47
+ type TView,
48
+ type TNode
49
+ } from '../../angular/vendor/lview/lViewOps';
50
+
51
+ type AngularCoreNamespace = {
52
+ createComponent: (
53
+ type: unknown,
54
+ options: {
55
+ hostElement?: Element;
56
+ environmentInjector: unknown;
57
+ }
58
+ ) => {
59
+ instance: unknown;
60
+ hostView: { _lView?: LView; detectChanges?: () => void };
61
+ destroy: () => void;
62
+ };
63
+ ApplicationRef?: unknown;
64
+ };
65
+
66
+ type ComponentClass = new (...args: unknown[]) => unknown;
67
+
68
+ type LiveInstance = {
69
+ host: Element;
70
+ oldLView: LView;
71
+ parentLView: LView;
72
+ slotIndex: number;
73
+ tNode: TNode;
74
+ };
75
+
76
+ /* Walk the DOM looking for elements whose component instance is of
77
+ * `Class`. Each match resolves to its parent LView + slot index via
78
+ * the LContext stored on the host element under `__ngContext__`.
79
+ *
80
+ * We walk DOM (not Angular's TRACKED_LVIEWS map) because (a)
81
+ * TRACKED_LVIEWS isn't exported and (b) the DOM walk is bounded by
82
+ * page size, which is fast enough for HMR. */
83
+ const findLiveInstances = (Class: ComponentClass): LiveInstance[] => {
84
+ const results: LiveInstance[] = [];
85
+ const elements = document.querySelectorAll('*');
86
+ for (const el of Array.from(elements)) {
87
+ const ctx = (el as unknown as Record<string, unknown>).__ngContext__;
88
+ if (typeof ctx !== 'object' || ctx === null) continue;
89
+ const lContext = ctx as { lView?: LView; nodeIndex?: number };
90
+ if (!lContext.lView || lContext.nodeIndex === undefined) continue;
91
+
92
+ const slot = lContext.lView[lContext.nodeIndex];
93
+ if (!isLView(slot)) continue;
94
+ const ownLView = slot as LView;
95
+ const instance = ownLView[CONTEXT];
96
+ if (!(instance instanceof Class)) continue;
97
+
98
+ const tNode = ownLView[T_HOST] as TNode | null;
99
+ const host = ownLView[HOST] as Element | null;
100
+ if (!tNode || !host) continue;
101
+
102
+ // Avoid double-recording the same LView (multiple DOM elements
103
+ // can land in the same component, all sharing __ngContext__)
104
+ if (results.some((r) => r.oldLView === ownLView)) continue;
105
+
106
+ results.push({
107
+ host,
108
+ oldLView: ownLView,
109
+ parentLView: lContext.lView,
110
+ slotIndex: lContext.nodeIndex,
111
+ tNode
112
+ });
113
+ }
114
+ return results;
115
+ };
116
+
117
+ /* Run a public `createComponent` call to instantiate `Class` at
118
+ * `hostElement`. Pulls ApplicationRef + EnvironmentInjector through
119
+ * the live app's injector exposed on `window.__ANGULAR_APP__`. */
120
+ const createFreshAt = (
121
+ Class: ComponentClass,
122
+ hostElement: Element,
123
+ core: AngularCoreNamespace
124
+ ): {
125
+ instance: unknown;
126
+ newLView: LView;
127
+ componentRef: ReturnType<AngularCoreNamespace['createComponent']>;
128
+ } | null => {
129
+ const w = window as unknown as {
130
+ __ANGULAR_APP__?: { injector: unknown };
131
+ };
132
+ const envInjector = w.__ANGULAR_APP__?.injector;
133
+ if (!envInjector) return null;
134
+
135
+ const ref = core.createComponent(Class, {
136
+ hostElement,
137
+ environmentInjector: envInjector
138
+ });
139
+
140
+ const newLView = ref.hostView._lView;
141
+ if (!newLView) {
142
+ // Should never happen — _lView is always populated by Angular's
143
+ // internal createComponent path. If it is missing, our slot
144
+ // constants might be off; bail to caller for fallback.
145
+ ref.destroy();
146
+ return null;
147
+ }
148
+
149
+ return { instance: ref.instance, newLView, componentRef: ref };
150
+ };
151
+
152
+ /* Splice `newLView` into `parentLView` at `slotIndex`, replacing
153
+ * `oldLView`. After the splice, the new LView lives in the parent's
154
+ * view tree; the old one is detached. */
155
+ const spliceLViewIntoParent = (
156
+ target: LiveInstance,
157
+ newLView: LView
158
+ ): void => {
159
+ const { parentLView, oldLView, slotIndex, tNode } = target;
160
+ replaceLViewInTree(parentLView, oldLView, newLView, slotIndex);
161
+ newLView[PARENT] = parentLView;
162
+ newLView[T_HOST] = tNode;
163
+ };
164
+
165
+ /* Fire onDestroy + cleanup on the OLD LView so subscriptions, event
166
+ * listeners, and `inject(DestroyRef).onDestroy(...)` callbacks all
167
+ * fire. Then mark the LView as destroyed so any subsequent
168
+ * tree-walk skips it. */
169
+ const teardownOldLView = (oldLView: LView): void => {
170
+ const oldTView = oldLView[TVIEW] as TView | null;
171
+ if (oldTView) {
172
+ executeOnDestroys(oldTView, oldLView);
173
+ processCleanups(oldTView, oldLView);
174
+ }
175
+ markLViewDestroyed(oldLView);
176
+ };
177
+
178
+ /* The fresh ComponentRef is registered as a root view on
179
+ * ApplicationRef. We don't want it tracked there — its parent in the
180
+ * view tree is the original parent LView. Detach it. */
181
+ const detachFromApplicationRoot = (
182
+ componentRef: { hostView: unknown },
183
+ core: AngularCoreNamespace
184
+ ): void => {
185
+ if (!core.ApplicationRef) return;
186
+ const w = window as unknown as {
187
+ __ANGULAR_APP__?: { detachView?: (view: unknown) => void };
188
+ };
189
+ w.__ANGULAR_APP__?.detachView?.(componentRef.hostView);
190
+ };
191
+
192
+ export type RemountResult = {
193
+ className: string;
194
+ remounted: number;
195
+ skipped: number;
196
+ error?: string;
197
+ };
198
+
199
+ /* Public entry. Called by the bundle's HMR listener block when an
200
+ * `angular:component-remount` event arrives for this class.
201
+ *
202
+ * applyMetadata is the surgical module's default export — it patches
203
+ * `Class.ɵcmp` with the new component definition. We call it BEFORE
204
+ * createComponent so the fresh instance picks up the new template,
205
+ * dependencies, etc.
206
+ *
207
+ * locals + namespaces match `ɵɵreplaceMetadata`'s contract — passed
208
+ * through to applyMetadata. We're not using ɵɵreplaceMetadata here
209
+ * (it preserves instance state, defeating the point), but we mirror
210
+ * the calling convention so bundle-level code stays consistent. */
211
+ export const remountComponentClass = async (
212
+ Class: ComponentClass,
213
+ applyMetadata: (
214
+ Class: unknown,
215
+ namespaces: unknown[],
216
+ ...locals: unknown[]
217
+ ) => void,
218
+ namespaces: unknown[],
219
+ locals: unknown[],
220
+ core: AngularCoreNamespace,
221
+ className: string
222
+ ): Promise<RemountResult> => {
223
+ try {
224
+ applyMetadata.apply(null, [Class, namespaces, ...locals]);
225
+ } catch (err) {
226
+ return {
227
+ className,
228
+ error: `applyMetadata threw: ${(err as Error).message}`,
229
+ remounted: 0,
230
+ skipped: 0
231
+ };
232
+ }
233
+
234
+ const targets = findLiveInstances(Class);
235
+ if (targets.length === 0) {
236
+ return { className, remounted: 0, skipped: 0 };
237
+ }
238
+
239
+ let remounted = 0;
240
+ let skipped = 0;
241
+
242
+ for (const target of targets) {
243
+ try {
244
+ const fresh = createFreshAt(Class, target.host, core);
245
+ if (!fresh) {
246
+ skipped++;
247
+ continue;
248
+ }
249
+
250
+ spliceLViewIntoParent(target, fresh.newLView);
251
+ detachFromApplicationRoot(fresh.componentRef, core);
252
+ teardownOldLView(target.oldLView);
253
+
254
+ fresh.componentRef.hostView.detectChanges?.();
255
+ remounted++;
256
+ } catch (err) {
257
+ console.error(
258
+ `[absolutejs] remount of ${className} failed at`,
259
+ target.host,
260
+ err
261
+ );
262
+ skipped++;
263
+ }
264
+ }
265
+
266
+ return { className, remounted, skipped };
267
+ };
@@ -0,0 +1,55 @@
1
+ import type {} from '../../../types/globals';
2
+ /* Wire `globalThis.__absAngularRemount` so the injected
3
+ * `__ng_hmr_remount` blocks (in `hmrInjectionPlugin.ts`) can call into
4
+ * the shared remount implementation. The bundle's listener captures
5
+ * the class via closure and the metadata via dynamic import; everything
6
+ * else is generic, so the implementation is shared rather than baked
7
+ * into every component bundle. */
8
+
9
+ import {
10
+ remountComponentClass,
11
+ type RemountResult
12
+ } from './angularRemount';
13
+
14
+ declare global {
15
+ // eslint-disable-next-line no-var
16
+ var __absAngularRemount:
17
+ | ((
18
+ Class: new (...args: unknown[]) => unknown,
19
+ applyMetadata: (
20
+ Class: unknown,
21
+ namespaces: unknown[],
22
+ ...locals: unknown[]
23
+ ) => void,
24
+ namespaces: unknown[],
25
+ locals: unknown[],
26
+ core: {
27
+ createComponent: (
28
+ type: unknown,
29
+ options: {
30
+ hostElement?: Element;
31
+ environmentInjector: unknown;
32
+ }
33
+ ) => {
34
+ instance: unknown;
35
+ hostView: {
36
+ _lView?: unknown[];
37
+ detectChanges?: () => void;
38
+ };
39
+ destroy: () => void;
40
+ };
41
+ ApplicationRef?: unknown;
42
+ },
43
+ className: string
44
+ ) => Promise<RemountResult>)
45
+ | undefined;
46
+ }
47
+
48
+ let installed = false;
49
+
50
+ export const installAngularRemountGlobal = (): void => {
51
+ if (installed) return;
52
+ if (typeof globalThis === 'undefined') return;
53
+ globalThis.__absAngularRemount = remountComponentClass;
54
+ installed = true;
55
+ };
@@ -13,7 +13,11 @@ import {
13
13
  } from './constants';
14
14
  import { detectCurrentFramework } from './frameworkDetect';
15
15
  import { hideErrorOverlay, showErrorOverlay } from './errorOverlay';
16
- import { dispatchAngularComponentUpdate } from './handlers/angularHmrShim';
16
+ import {
17
+ dispatchAngularComponentRemount,
18
+ dispatchAngularComponentUpdate
19
+ } from './handlers/angularHmrShim';
20
+ import { installAngularRemountGlobal } from './handlers/angularRemountWiring';
17
21
  import { handleReactUpdate } from './handlers/react';
18
22
  import { handleHTMLUpdate, handleScriptUpdate } from './handlers/html';
19
23
  import { handleHTMXUpdate } from './handlers/htmx';
@@ -30,6 +34,7 @@ import {
30
34
 
31
35
  // Initialize HMR globals
32
36
  if (typeof window !== 'undefined') {
37
+ installAngularRemountGlobal();
33
38
  if (!window.__HMR_MANIFEST__) {
34
39
  window.__HMR_MANIFEST__ = {};
35
40
  }
@@ -69,6 +74,7 @@ window.addEventListener('unhandledrejection', (evt) => {
69
74
 
70
75
  const hmrUpdateTypes = new Set([
71
76
  'angular:component-update',
77
+ 'angular:component-remount',
72
78
  'angular:rebootstrap',
73
79
  'react-update',
74
80
  'html-update',
@@ -169,6 +175,28 @@ const handleHMRMessage = (message: HMRMessage) => {
169
175
  }
170
176
  break;
171
177
  }
178
+ case 'angular:component-remount': {
179
+ // Tier 1a per-component remount. Structural change
180
+ // detected in fastHmr — the existing instance lacks new
181
+ // fields / DI / providers, so we destroy + recreate just
182
+ // this component (vs. full app rebootstrap). The injected
183
+ // `__ng_hmr_remount` listener handles the splice via the
184
+ // `__absAngularRemount` global wired in
185
+ // `installAngularRemountGlobal`.
186
+ const data = message.data as
187
+ | { id?: string; timestamp?: number }
188
+ | undefined;
189
+ if (data && typeof data.id === 'string') {
190
+ dispatchAngularComponentRemount({
191
+ id: data.id,
192
+ timestamp:
193
+ typeof data.timestamp === 'number'
194
+ ? data.timestamp
195
+ : Date.now()
196
+ });
197
+ }
198
+ break;
199
+ }
172
200
  case 'angular:rebootstrap': {
173
201
  // Tier 1 fallback. The user's edit changed structure
174
202
  // the surgical path can't safely apply
package/dist/index.js CHANGED
@@ -9876,12 +9876,50 @@ var ENTITY_DECORATOR_RE, buildHmrTail = (className, encodedIdLiteral) => `
9876
9876
  u.default(${className}, [core]);
9877
9877
  }
9878
9878
  };
9879
+ // Tier 1 remount: structural changes (new ctor params / new field
9880
+ // initializers / new providers) make a CONTEXT-preserving replace
9881
+ // unsafe \u2014 the existing instance lacks the new fields. The remount
9882
+ // path tears down the live LView and re-creates it via public
9883
+ // \`createComponent\` against the same host, so the new constructor
9884
+ // runs with fresh DI, new lifecycle hooks fire, and the splice
9885
+ // logic puts the result back in the parent's view tree. The
9886
+ // shared implementation is on \`globalThis.__absAngularRemount\` \u2014
9887
+ // installed by hmrClient.ts's import-time wiring.
9888
+ const __ng_hmr_remount = async (t) => {
9889
+ const [u, core] = await Promise.all([
9890
+ import('/@ng/component?c=' + encodeURIComponent(__ng_hmr_id) + '&t=' + t),
9891
+ import('@angular/core')
9892
+ ]);
9893
+ if (!u || typeof u.default !== 'function') return;
9894
+ if (typeof globalThis.__absAngularRemount === 'function' && ${className}.\u0275cmp) {
9895
+ try {
9896
+ await globalThis.__absAngularRemount(
9897
+ ${className},
9898
+ u.default,
9899
+ [core],
9900
+ [],
9901
+ core,
9902
+ ${JSON.stringify(className)}
9903
+ );
9904
+ } catch (err) {
9905
+ console.error('[abs-hmr] remount threw for ${className}:', err);
9906
+ }
9907
+ } else {
9908
+ // No remount helper installed (older absolutejs runtime, or
9909
+ // non-component entity). Fall back to surgical replace.
9910
+ u.default(${className}, [core]);
9911
+ }
9912
+ };
9913
+
9879
9914
  if (typeof globalThis !== 'undefined' &&
9880
9915
  globalThis.__angularHmr &&
9881
9916
  typeof globalThis.__angularHmr.on === 'function') {
9882
9917
  globalThis.__angularHmr.on('angular:component-update', (d) => {
9883
9918
  if (d && d.id === __ng_hmr_id) __ng_hmr_load(d.timestamp);
9884
9919
  });
9920
+ globalThis.__angularHmr.on('angular:component-remount', (d) => {
9921
+ if (d && d.id === __ng_hmr_id) __ng_hmr_remount(d.timestamp);
9922
+ });
9885
9923
  }
9886
9924
  }
9887
9925
  `, createAngularHmrInjectionPlugin = (params) => {
@@ -18929,7 +18967,12 @@ ${block}
18929
18967
  if (!moduleText) {
18930
18968
  return fail("unexpected-error", `buildSimpleEntityModule returned null for ${className}`);
18931
18969
  }
18932
- return { componentSource: sourceFile, moduleText, ok: true };
18970
+ return {
18971
+ componentSource: sourceFile,
18972
+ fingerprintChanged: false,
18973
+ moduleText,
18974
+ ok: true
18975
+ };
18933
18976
  }
18934
18977
  if (inheritsDecoratedClass(classNode)) {
18935
18978
  return fail("inherits-decorated-class");
@@ -18984,9 +19027,7 @@ ${block}
18984
19027
  const fingerprintId = encodeURIComponent(`${projectRelPath}@${className}`);
18985
19028
  const currentFingerprint = extractFingerprint(classNode, className, decoratorMeta, inputs, outputs, sourceFile, componentDir);
18986
19029
  const cachedFingerprint = fingerprintCache.get(fingerprintId);
18987
- if (cachedFingerprint && !fingerprintsEqual(cachedFingerprint, currentFingerprint)) {
18988
- return fail("structural-change", `fingerprint changed for ${className}; escalate to Tier 1`);
18989
- }
19030
+ const fingerprintChanged = cachedFingerprint !== undefined && !fingerprintsEqual(cachedFingerprint, currentFingerprint);
18990
19031
  const sourceFileObj = new compiler.ParseSourceFile(tsSource, componentFilePath);
18991
19032
  const zeroLoc = new compiler.ParseLocation(sourceFileObj, 0, 0, 0);
18992
19033
  const typeSourceSpan = new compiler.ParseSourceSpan(zeroLoc, zeroLoc);
@@ -19091,7 +19132,12 @@ ${block}
19091
19132
  }
19092
19133
  }
19093
19134
  fingerprintCache.set(fingerprintId, currentFingerprint);
19094
- return { ok: true, moduleText, componentSource: sourceFile };
19135
+ return {
19136
+ componentSource: sourceFile,
19137
+ fingerprintChanged,
19138
+ moduleText,
19139
+ ok: true
19140
+ };
19095
19141
  } catch (err) {
19096
19142
  return fail("unexpected-error", String(err));
19097
19143
  }
@@ -19891,6 +19937,7 @@ var moduleServerPromise, getModuleServer = () => moduleServerPromise, runSequent
19891
19937
  const { tryFastHmr: tryFastHmr2 } = await Promise.resolve().then(() => (init_fastHmrCompiler(), exports_fastHmrCompiler));
19892
19938
  const queue = [];
19893
19939
  const queueIds = new Set;
19940
+ let anyFingerprintChanged = false;
19894
19941
  for (const editedFile of userEdited) {
19895
19942
  const owners = resolveOwningComponents2({
19896
19943
  changedFilePath: editedFile,
@@ -19898,6 +19945,7 @@ var moduleServerPromise, getModuleServer = () => moduleServerPromise, runSequent
19898
19945
  });
19899
19946
  if (owners.length === 0 && (editedFile.endsWith(".component.ts") || editedFile.endsWith(".directive.ts") || editedFile.endsWith(".pipe.ts") || editedFile.endsWith(".service.ts"))) {
19900
19947
  return {
19948
+ kind: "rebootstrap",
19901
19949
  reason: `no Angular-decorated class found in ${editedFile}`,
19902
19950
  tier: 1
19903
19951
  };
@@ -19913,14 +19961,21 @@ var moduleServerPromise, getModuleServer = () => moduleServerPromise, runSequent
19913
19961
  });
19914
19962
  if (!result.ok) {
19915
19963
  return {
19964
+ kind: "rebootstrap",
19916
19965
  reason: `${className}: ${result.reason}${result.detail ? ` (${result.detail})` : ""}`,
19917
19966
  tier: 1
19918
19967
  };
19919
19968
  }
19969
+ if (result.fingerprintChanged) {
19970
+ anyFingerprintChanged = true;
19971
+ }
19920
19972
  queueIds.add(id);
19921
19973
  queue.push({ className, id });
19922
19974
  }
19923
19975
  }
19976
+ if (anyFingerprintChanged) {
19977
+ return { kind: "remount", queue, tier: 1 };
19978
+ }
19924
19979
  return { queue, tier: 0 };
19925
19980
  }, broadcastSurgical = (state, queue) => {
19926
19981
  const timestamp = Date.now();
@@ -19931,6 +19986,15 @@ var moduleServerPromise, getModuleServer = () => moduleServerPromise, runSequent
19931
19986
  });
19932
19987
  logInfo(`[ng-hmr broadcast] ${className}`);
19933
19988
  }
19989
+ }, broadcastRemount = (state, queue) => {
19990
+ const timestamp = Date.now();
19991
+ for (const { id, className } of queue) {
19992
+ broadcastToClients(state, {
19993
+ data: { id, timestamp },
19994
+ type: "angular:component-remount"
19995
+ });
19996
+ logInfo(`[ng-hmr tier-1 remount] ${className}`);
19997
+ }
19934
19998
  }, broadcastRebootstrap = async (state, reason) => {
19935
19999
  logInfo(`[ng-hmr tier-1 rebootstrap] ${reason}`);
19936
20000
  broadcastToClients(state, {
@@ -19994,7 +20058,12 @@ var moduleServerPromise, getModuleServer = () => moduleServerPromise, runSequent
19994
20058
  runBundle().catch((err) => {
19995
20059
  logWarn(`[ng-hmr async bundle] rebuild failed: ${err instanceof Error ? err.message : String(err)}`);
19996
20060
  });
19997
- } else {
20061
+ } else if (verdict.tier === 1 && verdict.kind === "remount") {
20062
+ broadcastRemount(state, verdict.queue);
20063
+ runBundle().catch((err) => {
20064
+ logWarn(`[ng-hmr async bundle] rebuild failed: ${err instanceof Error ? err.message : String(err)}`);
20065
+ });
20066
+ } else if (verdict.tier === 1 && verdict.kind === "rebootstrap") {
19998
20067
  await runBundle();
19999
20068
  await broadcastRebootstrap(state, verdict.reason);
20000
20069
  }
@@ -30289,5 +30358,5 @@ export {
30289
30358
  ANGULAR_INIT_TIMEOUT_MS
30290
30359
  };
30291
30360
 
30292
- //# debugId=FEFC595D5DEBE05064756E2164756E21
30361
+ //# debugId=F19AC49C80B89ABF64756E2164756E21
30293
30362
  //# sourceMappingURL=index.js.map