@nativescript/angular 21.0.1-alpha.1 → 21.0.1-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.
@@ -364,6 +364,7 @@ class NativeScriptDebug {
364
364
  static { this.routeReuseStrategyTraceCategory = 'ns-route-reuse-strategy'; }
365
365
  static { this.listViewTraceCategory = 'ns-list-view'; }
366
366
  static { this.bootstrapCategory = 'bootstrap'; }
367
+ static { this.hmrTraceCategory = 'ns-ng-hmr'; }
367
368
  // TODO: migrate all usage to this - avoids extraneous method executions
368
369
  static { this.enabled = Trace.isEnabled(); }
369
370
  static isLogEnabled() {
@@ -405,6 +406,12 @@ class NativeScriptDebug {
405
406
  static bootstrapLogError(message) {
406
407
  Trace.write(message, NativeScriptDebug.bootstrapCategory, Trace.messageType.error);
407
408
  }
409
+ static hmrLog(message) {
410
+ Trace.write(message, NativeScriptDebug.hmrTraceCategory);
411
+ }
412
+ static hmrLogError(message) {
413
+ Trace.write(message, NativeScriptDebug.hmrTraceCategory, Trace.messageType.error);
414
+ }
408
415
  }
409
416
 
410
417
  class FrameService {
@@ -1591,11 +1598,9 @@ function runNativeScriptAngularApp(options) {
1591
1598
  if (clearedDetached > 0 ||
1592
1599
  cleared > 0 ||
1593
1600
  (clearedLocation && (clearedLocation.outlets > 0 || clearedLocation.states > 0 || clearedLocation.callbacks > 0 || clearedLocation.hadUrlTree))) {
1594
- console.log('[ng-hmr] cleared Angular route caches before reboot:', {
1595
- detachedViews: clearedDetached,
1596
- locationState: clearedLocation,
1597
- routeFields: cleared,
1598
- });
1601
+ if (NativeScriptDebug.isLogEnabled()) {
1602
+ NativeScriptDebug.hmrLog(`cleared Angular route caches before reboot: detachedViews=${clearedDetached} routeFields=${cleared} locationState=${JSON.stringify(clearedLocation)}`);
1603
+ }
1599
1604
  }
1600
1605
  }
1601
1606
  catch { }
@@ -1625,21 +1630,30 @@ function runNativeScriptAngularApp(options) {
1625
1630
  }, 0);
1626
1631
  };
1627
1632
  const setRootView = (ref) => {
1628
- console.log('[ng-hmr] setRootView called, bootstrapId:', bootstrapId, 'ref type:', ref?.constructor?.name);
1633
+ const traceEnabled = NativeScriptDebug.isLogEnabled();
1634
+ if (traceEnabled) {
1635
+ NativeScriptDebug.hmrLog(`setRootView called bootstrapId=${bootstrapId} refType=${ref?.constructor?.name}`);
1636
+ }
1629
1637
  if (bootstrapId === -1) {
1630
- // treat edge cases
1631
- console.log('[ng-hmr] setRootView: bootstrapId is -1, returning early');
1638
+ // edge case: a stale ref racing with a teardown
1639
+ if (traceEnabled) {
1640
+ NativeScriptDebug.hmrLog('setRootView: bootstrapId is -1, returning early');
1641
+ }
1632
1642
  return;
1633
1643
  }
1634
1644
  if (ref instanceof NgModuleRef || ref instanceof ApplicationRef) {
1635
1645
  if (ref.injector.get(DISABLE_ROOT_VIEW_HANDLING, false)) {
1636
- console.log('[ng-hmr] setRootView: DISABLE_ROOT_VIEW_HANDLING is true, returning');
1646
+ if (traceEnabled) {
1647
+ NativeScriptDebug.hmrLog('setRootView: DISABLE_ROOT_VIEW_HANDLING is true, returning');
1648
+ }
1637
1649
  return;
1638
1650
  }
1639
1651
  }
1640
1652
  else {
1641
1653
  if (ref['__disable_root_view_handling']) {
1642
- console.log('[ng-hmr] setRootView: __disable_root_view_handling is true, returning');
1654
+ if (traceEnabled) {
1655
+ NativeScriptDebug.hmrLog('setRootView: __disable_root_view_handling is true, returning');
1656
+ }
1643
1657
  return;
1644
1658
  }
1645
1659
  }
@@ -1647,8 +1661,8 @@ function runNativeScriptAngularApp(options) {
1647
1661
  NativeScriptDebug.bootstrapLog(`Setting RootView ${launchEventDone ? 'outside of' : 'during'} launch event`);
1648
1662
  // TODO: check for leaks when root view isn't properly destroyed
1649
1663
  if (ref instanceof View) {
1650
- console.log('[ng-hmr] setRootView: ref is View, launchEventDone:', launchEventDone);
1651
- if (NativeScriptDebug.isLogEnabled()) {
1664
+ if (traceEnabled) {
1665
+ NativeScriptDebug.hmrLog(`setRootView: ref is View, launchEventDone=${launchEventDone}`);
1652
1666
  NativeScriptDebug.bootstrapLog(`Setting RootView to ${ref}`);
1653
1667
  }
1654
1668
  if (currentOptions.embedded) {
@@ -1665,38 +1679,34 @@ function runNativeScriptAngularApp(options) {
1665
1679
  }
1666
1680
  const view = ref.injector.get(APP_ROOT_VIEW);
1667
1681
  const newRoot = view instanceof AppHostView ? view.content : view;
1668
- console.log('[ng-hmr] setRootView: view from injector:', view?.constructor?.name, 'newRoot:', newRoot?.constructor?.name);
1669
- console.log('[ng-hmr] setRootView: launchEventDone:', launchEventDone, 'embedded:', currentOptions.embedded);
1670
- if (NativeScriptDebug.isLogEnabled()) {
1682
+ if (traceEnabled) {
1683
+ NativeScriptDebug.hmrLog(`setRootView: view=${view?.constructor?.name} newRoot=${newRoot?.constructor?.name} launchEventDone=${launchEventDone} embedded=${!!currentOptions.embedded}`);
1671
1684
  NativeScriptDebug.bootstrapLog(`Setting RootView to ${newRoot}`);
1672
1685
  }
1673
1686
  if (currentOptions.embedded) {
1674
- console.log('[ng-hmr] setRootView: calling Application.run (embedded)');
1687
+ if (traceEnabled) {
1688
+ NativeScriptDebug.hmrLog('setRootView: calling Application.run (embedded)');
1689
+ }
1675
1690
  Application.run({ create: () => newRoot });
1676
1691
  }
1677
1692
  else if (launchEventDone) {
1678
- console.log('[ng-hmr] setRootView: calling Application.resetRootView');
1679
- console.log('[ng-hmr] setRootView: newRoot details:', {
1680
- type: newRoot?.constructor?.name,
1681
- nativeView: !!newRoot?.nativeView,
1682
- parent: newRoot?.parent?.constructor?.name,
1683
- childCount: newRoot?.getChildrenCount?.() ?? 'N/A',
1684
- });
1693
+ if (traceEnabled) {
1694
+ NativeScriptDebug.hmrLog(`setRootView: calling Application.resetRootView newRoot type=${newRoot?.constructor?.name} hasNativeView=${!!newRoot?.nativeView} parent=${newRoot?.parent?.constructor?.name} childCount=${newRoot?.getChildrenCount?.() ?? 'N/A'}`);
1695
+ }
1685
1696
  rootTransitionGuard.runApplicationResetRootView(Application, () => newRoot, newRoot?.constructor?.name || 'View');
1686
1697
  refreshRootViewCss(newRoot);
1687
- console.log('[ng-hmr] setRootView: Application.resetRootView returned');
1688
- // Check root view after reset
1689
- setTimeout(() => {
1690
- const currentRoot = Application.getRootView();
1691
- console.log('[ng-hmr] setRootView: after reset, getRootView:', {
1692
- type: currentRoot?.constructor?.name,
1693
- nativeView: !!currentRoot?.nativeView,
1694
- childCount: currentRoot?.getChildrenCount?.() ?? 'N/A',
1695
- });
1696
- }, 100);
1698
+ if (traceEnabled) {
1699
+ NativeScriptDebug.hmrLog('setRootView: Application.resetRootView returned');
1700
+ setTimeout(() => {
1701
+ const currentRoot = Application.getRootView();
1702
+ NativeScriptDebug.hmrLog(`setRootView: post-reset getRootView type=${currentRoot?.constructor?.name} hasNativeView=${!!currentRoot?.nativeView} childCount=${currentRoot?.getChildrenCount?.() ?? 'N/A'}`);
1703
+ }, 100);
1704
+ }
1697
1705
  }
1698
1706
  else {
1699
- console.log('[ng-hmr] setRootView: setting targetRootView (launch in progress)');
1707
+ if (traceEnabled) {
1708
+ NativeScriptDebug.hmrLog('setRootView: setting targetRootView (launch in progress)');
1709
+ }
1700
1710
  targetRootView = newRoot;
1701
1711
  }
1702
1712
  };
@@ -1708,25 +1718,34 @@ function runNativeScriptAngularApp(options) {
1708
1718
  setRootView(errorTextBox);
1709
1719
  };
1710
1720
  const bootstrapRoot = (reason) => {
1711
- console.log('[ng-hmr] bootstrapRoot called, reason:', reason);
1721
+ if (NativeScriptDebug.isLogEnabled()) {
1722
+ NativeScriptDebug.hmrLog(`bootstrapRoot called reason=${reason}`);
1723
+ }
1712
1724
  try {
1713
1725
  if (reason === 'hotreload') {
1714
1726
  resetAngularHmrCompiledComponents(getAngularCoreForHmrReset(i0, globalThis));
1715
1727
  }
1716
1728
  bootstrapId = Date.now();
1717
- console.log('[ng-hmr] bootstrapRoot: new bootstrapId:', bootstrapId);
1729
+ if (NativeScriptDebug.isLogEnabled()) {
1730
+ NativeScriptDebug.hmrLog(`bootstrapRoot: new bootstrapId=${bootstrapId}`);
1731
+ }
1718
1732
  const currentBootstrapId = bootstrapId;
1719
1733
  let bootstrapped = false;
1720
1734
  let onMainBootstrap = () => {
1721
1735
  setRootView(mainModuleRef);
1722
1736
  };
1723
1737
  runSynchronously(() => currentOptions.appModuleBootstrap(reason).then((ref) => {
1724
- console.log('[ng-hmr] appModuleBootstrap resolved, ref:', ref?.constructor?.name);
1725
- console.log('[ng-hmr] currentBootstrapId:', currentBootstrapId, 'bootstrapId:', bootstrapId);
1738
+ if (NativeScriptDebug.isLogEnabled()) {
1739
+ NativeScriptDebug.hmrLog(`appModuleBootstrap resolved ref=${ref?.constructor?.name} currentBootstrapId=${currentBootstrapId} bootstrapId=${bootstrapId}`);
1740
+ }
1726
1741
  if (currentBootstrapId !== bootstrapId) {
1727
- // this module is old and not needed anymore
1728
- // this may happen when developer uses async app initializer and the user exits the app before this bootstraps
1729
- console.log('[ng-hmr] bootstrap ID mismatch, destroying ref');
1742
+ // The pending bootstrap resolved AFTER another reboot bumped
1743
+ // bootstrapId. This typically happens when a developer ships
1744
+ // an async APP_INITIALIZER and the user exits/re-enters the
1745
+ // app while it's still resolving. Drop this ref.
1746
+ if (NativeScriptDebug.isLogEnabled()) {
1747
+ NativeScriptDebug.hmrLog('bootstrap ID mismatch, destroying ref');
1748
+ }
1730
1749
  ref.destroy();
1731
1750
  return;
1732
1751
  }
@@ -1748,41 +1767,49 @@ function runNativeScriptAngularApp(options) {
1748
1767
  };
1749
1768
  runInZone(() => {
1750
1769
  mainModuleRef = ref;
1751
- // Expose ApplicationRef for HMR to trigger change detection
1752
- // Check for ApplicationRef by duck-typing since instanceof can fail across module realms
1770
+ // Expose ApplicationRef for HMR to trigger change detection.
1771
+ // Check by duck-typing because `instanceof` can fail across
1772
+ // module realms during HMR — we may be holding a fresh
1773
+ // ApplicationRef class while `ref` was constructed by an
1774
+ // earlier (now-evicted) realm copy.
1753
1775
  const refAny = ref;
1754
1776
  const isAppRef = refAny && typeof refAny.tick === 'function' && Array.isArray(refAny.components);
1755
- console.log('[ng-hmr] ref type check: isAppRef=', isAppRef, 'has tick=', typeof refAny?.tick === 'function', 'has components=', Array.isArray(refAny?.components));
1777
+ if (NativeScriptDebug.isLogEnabled()) {
1778
+ NativeScriptDebug.hmrLog(`ref type check isAppRef=${isAppRef} hasTick=${typeof refAny?.tick === 'function'} hasComponents=${Array.isArray(refAny?.components)}`);
1779
+ }
1756
1780
  if (isAppRef) {
1757
1781
  global['__NS_ANGULAR_APP_REF__'] = ref;
1758
- // Mark boot complete for the HMR system
1759
1782
  global['__NS_HMR_BOOT_COMPLETE__'] = true;
1760
- // Register bootstrapped components for HMR lookup
1761
1783
  if (!global['__NS_ANGULAR_COMPONENTS__']) {
1762
1784
  global['__NS_ANGULAR_COMPONENTS__'] = {};
1763
1785
  }
1764
- // Get the component class from the first bootstrapped component
1765
- console.log('[ng-hmr] ApplicationRef components count:', refAny.components?.length);
1786
+ if (NativeScriptDebug.isLogEnabled()) {
1787
+ NativeScriptDebug.hmrLog(`ApplicationRef components count=${refAny.components?.length ?? 0}`);
1788
+ }
1766
1789
  if (refAny.components && refAny.components.length > 0) {
1767
1790
  const componentRef = refAny.components[0];
1768
- console.log('[ng-hmr] componentRef:', componentRef?.constructor?.name);
1769
- console.log('[ng-hmr] componentRef.componentType:', componentRef?.componentType?.name);
1770
- // For Angular 17+ standalone components, the component type is on componentRef.componentType
1771
- // For older Angular, try componentRef.instance.constructor
1791
+ if (NativeScriptDebug.isLogEnabled()) {
1792
+ NativeScriptDebug.hmrLog(`componentRef=${componentRef?.constructor?.name} componentType=${componentRef?.componentType?.name}`);
1793
+ }
1794
+ // Angular 17+ standalone: the component class is on
1795
+ // `componentRef.componentType`. Older Angular keeps it on
1796
+ // `componentRef.instance.constructor`.
1772
1797
  let componentType = componentRef?.componentType;
1773
1798
  if (!componentType && componentRef?.instance) {
1774
1799
  componentType = componentRef.instance.constructor;
1775
1800
  }
1776
1801
  if (componentType && componentType.name) {
1777
1802
  global['__NS_ANGULAR_COMPONENTS__'][componentType.name] = componentType;
1778
- console.log('[ng-hmr] Registered component for HMR:', componentType.name);
1803
+ if (NativeScriptDebug.isLogEnabled()) {
1804
+ NativeScriptDebug.hmrLog(`registered component for HMR: ${componentType.name}`);
1805
+ }
1779
1806
  }
1780
- else {
1781
- console.log('[ng-hmr] Could not get componentType name');
1807
+ else if (NativeScriptDebug.isLogEnabled()) {
1808
+ NativeScriptDebug.hmrLog('could not resolve componentType name');
1782
1809
  }
1783
1810
  }
1784
- else {
1785
- console.log('[ng-hmr] No components in ApplicationRef');
1811
+ else if (NativeScriptDebug.isLogEnabled()) {
1812
+ NativeScriptDebug.hmrLog('no components in ApplicationRef');
1786
1813
  }
1787
1814
  }
1788
1815
  else {
@@ -1958,20 +1985,28 @@ function runNativeScriptAngularApp(options) {
1958
1985
  disposePlatform('hotreload');
1959
1986
  };
1960
1987
  global['__reboot_ng_modules__'] = (shouldDisposePlatform = false) => {
1961
- console.log('[ng-hmr] __reboot_ng_modules__ called, shouldDisposePlatform:', shouldDisposePlatform);
1962
- console.log('[ng-hmr] current bootstrapId:', bootstrapId, 'mainModuleRef:', !!mainModuleRef);
1988
+ const traceEnabled = NativeScriptDebug.isLogEnabled();
1989
+ if (traceEnabled) {
1990
+ NativeScriptDebug.hmrLog(`__reboot_ng_modules__ called shouldDisposePlatform=${shouldDisposePlatform} bootstrapId=${bootstrapId} hasMainModuleRef=${!!mainModuleRef}`);
1991
+ }
1963
1992
  try {
1964
1993
  global['__NS_CAPTURE_ANGULAR_HMR_ROUTE__']?.();
1965
1994
  }
1966
1995
  catch { }
1967
1996
  disposeLastModules('hotreload');
1968
- console.log('[ng-hmr] after disposeLastModules, bootstrapId:', bootstrapId);
1997
+ if (traceEnabled) {
1998
+ NativeScriptDebug.hmrLog(`after disposeLastModules bootstrapId=${bootstrapId}`);
1999
+ }
1969
2000
  if (shouldDisposePlatform) {
1970
2001
  disposePlatform('hotreload');
1971
2002
  }
1972
- console.log('[ng-hmr] calling bootstrapRoot...');
2003
+ if (traceEnabled) {
2004
+ NativeScriptDebug.hmrLog('calling bootstrapRoot');
2005
+ }
1973
2006
  bootstrapRoot('hotreload');
1974
- console.log('[ng-hmr] bootstrapRoot returned, new bootstrapId:', bootstrapId);
2007
+ if (traceEnabled) {
2008
+ NativeScriptDebug.hmrLog(`bootstrapRoot returned bootstrapId=${bootstrapId}`);
2009
+ }
1975
2010
  };
1976
2011
  if (isWebpackHot) {
1977
2012
  // Webpack-specific HMR handling
@@ -2224,13 +2259,15 @@ function printNgTree(view) {
2224
2259
  }
2225
2260
  function printChildrenRecurse(parent) {
2226
2261
  const children = parent.firstChild ? [parent.firstChild, ...getChildrenSiblings(parent.firstChild).nextSiblings] : [];
2227
- console.log(`parent: ${parent}, firstChild: ${parent.firstChild}, lastChild: ${parent.lastChild} children: ${children}`);
2228
- if (parent.firstChild) {
2229
- console.log(`----- start ${parent}`);
2262
+ if (NativeScriptDebug.isLogEnabled()) {
2263
+ NativeScriptDebug.viewUtilLog(`parent: ${parent}, firstChild: ${parent.firstChild}, lastChild: ${parent.lastChild} children: ${children}`);
2264
+ if (parent.firstChild) {
2265
+ NativeScriptDebug.viewUtilLog(`----- start ${parent}`);
2266
+ }
2230
2267
  }
2231
2268
  children.forEach((c) => printChildrenRecurse(c));
2232
- if (parent.firstChild) {
2233
- console.log(`----- end ${parent}`);
2269
+ if (parent.firstChild && NativeScriptDebug.isLogEnabled()) {
2270
+ NativeScriptDebug.viewUtilLog(`----- end ${parent}`);
2234
2271
  }
2235
2272
  }
2236
2273
  function getChildrenSiblings(view) {
@@ -2252,8 +2289,10 @@ function getChildrenSiblings(view) {
2252
2289
  };
2253
2290
  }
2254
2291
  function printSiblingsTree(view) {
2292
+ if (!NativeScriptDebug.isLogEnabled())
2293
+ return;
2255
2294
  const { previousSiblings, nextSiblings } = getChildrenSiblings(view);
2256
- console.log(`${view} previousSiblings: ${previousSiblings} nextSiblings: ${nextSiblings}`);
2295
+ NativeScriptDebug.viewUtilLog(`${view} previousSiblings: ${previousSiblings} nextSiblings: ${nextSiblings}`);
2257
2296
  }
2258
2297
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
2259
2298
  const propertyMaps = new Map();
@@ -5402,7 +5441,7 @@ function createApplication(options) {
5402
5441
  * @deprecated use runNativeScriptAngularApp instead
5403
5442
  */
5404
5443
  const platformNativeScriptDynamic = function (options, extraProviders) {
5405
- console.log('platformNativeScriptDynamic is deprecated, use runNativeScriptAngularApp instead');
5444
+ console.warn('platformNativeScriptDynamic is deprecated, use runNativeScriptAngularApp instead');
5406
5445
  options = options || {};
5407
5446
  extraProviders = extraProviders || [];
5408
5447
  const ngRootView = new AppHostView(new Color(options.backgroundColor || 'white'));