@nativescript/angular 21.0.1-alpha.3 → 21.0.1-alpha.4

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.
@@ -6426,11 +6426,18 @@ let NativeModalRef = class NativeModalRef {
6426
6426
  this._closeCallback = once(async () => {
6427
6427
  this.stateChanged.next({ state: 'closing' });
6428
6428
  if (!this._isDismissed) {
6429
- this.modalViewRef.firstNativeLikeView?.closeModal();
6429
+ // Prefer `modalView` (the actual presented view) over the
6430
+ // legacy `firstNativeLikeView`. Both paths ultimately reach
6431
+ // the same `_closeModalCallback` via parent walk, but going
6432
+ // through the presented view is one hop instead of three and
6433
+ // works even if the rendered first root has been replaced by
6434
+ // an HMR `ɵɵreplaceMetadata` cycle.
6435
+ const closeTarget = this.modalView ?? this.modalViewRef.firstNativeLikeView;
6436
+ closeTarget?.closeModal();
6430
6437
  }
6431
6438
  await this.location?._closeModalNavigation();
6432
6439
  // this.detachedLoaderRef?.destroy();
6433
- if (this.modalViewRef?.firstNativeLikeView.isLoaded) {
6440
+ if (this.modalViewRef?.firstNativeLikeView?.isLoaded) {
6434
6441
  fromEvent(this.modalViewRef.firstNativeLikeView, 'unloaded')
6435
6442
  .pipe(take(1))
6436
6443
  .subscribe(() => this.stateChanged.next({ state: 'closed' }));
@@ -6483,19 +6490,34 @@ let NativeModalRef = class NativeModalRef {
6483
6490
  }
6484
6491
  attachComponentPortal(portal) {
6485
6492
  this.startModalNavigation();
6493
+ // `targetView` is a stable ContentView wrapper we own. The Angular
6494
+ // component's host (a `ProxyViewContainer`) is attached as its
6495
+ // content via the portal outlet below. We present `targetView`
6496
+ // itself as the modal — *not* the first rendered template root —
6497
+ // so that component-level HMR (`ɵɵreplaceMetadata`) can re-render
6498
+ // into the PVC and the modal automatically displays the new
6499
+ // content via the wrapper. Presenting the rendered first root
6500
+ // directly worked for the initial open but left subsequent HMR
6501
+ // updates rendering into a detached PVC, producing a blank modal.
6486
6502
  const targetView = new ContentView();
6487
6503
  this.portalOutlet = new NativeScriptDomPortalOutlet(targetView, this._config.componentFactoryResolver || this._injector.get(ComponentFactoryResolver), this._injector.get(ApplicationRef), this._injector);
6488
6504
  const componentRef = this.portalOutlet.attach(portal);
6489
6505
  componentRef.changeDetectorRef.detectChanges();
6490
6506
  this.modalViewRef = new NgViewRef(componentRef);
6507
+ this.modalView = targetView;
6491
6508
  if (this.modalViewRef.firstNativeLikeView !== this.modalViewRef.view) {
6492
6509
  this.modalViewRef.view._ngDialogRoot = this.modalViewRef.firstNativeLikeView;
6493
6510
  }
6494
- this.modalViewRef.firstNativeLikeView['__ng_modal_id__'] = this._id;
6495
- // if we don't detach the view from its parent, ios gets mad
6496
- this.modalViewRef.detachNativeLikeView();
6511
+ // Tag both the wrapper (the actual modal root) and the rendered
6512
+ // first root so `getClosestDialog`'s parent walk finds the modal
6513
+ // id regardless of whether it starts from a view inside the
6514
+ // template or from the wrapper.
6515
+ targetView['__ng_modal_id__'] = this._id;
6516
+ if (this.modalViewRef.firstNativeLikeView) {
6517
+ this.modalViewRef.firstNativeLikeView['__ng_modal_id__'] = this._id;
6518
+ }
6497
6519
  const userOptions = this._config.nativeOptions || {};
6498
- this.parentView.showModal(this.modalViewRef.firstNativeLikeView, {
6520
+ this.parentView.showModal(targetView, {
6499
6521
  context: null,
6500
6522
  ...userOptions,
6501
6523
  closeCallback: async () => {
@@ -7360,6 +7382,513 @@ function generateNativeScriptView(typeOrTemplate, options) {
7360
7382
  return viewRef;
7361
7383
  }
7362
7384
 
7385
+ /**
7386
+ * Framework-agnostic Hot-Module-Replacement state cache.
7387
+ *
7388
+ * The {@link HmrCacheStore} class is intentionally free of any Angular
7389
+ * imports so a future `@nativescript/solid` (or any other framework
7390
+ * binding) can lift this file as-is and wrap it with its own DI
7391
+ * primitive. The Angular DI wrapper lives in
7392
+ * `./hmr-cache.service.ts`.
7393
+ *
7394
+ * # What it does
7395
+ *
7396
+ * The NativeScript iOS runtime exposes a Vite-spec compliant
7397
+ * `import.meta.hot` on every imported module (see
7398
+ * `@nativescript/ios` →
7399
+ * `runtime/HMRSupport.{h,mm}::InitializeImportMetaHot`). The runtime
7400
+ * keeps a per-module persistent `data` object alive in C++ across V8
7401
+ * evaluation cycles and canonicalizes the module path so the same
7402
+ * bucket survives the URL variations Vite cycles through during a
7403
+ * save (HMR boot/live tags, versioned bridge paths, common script
7404
+ * extensions). When `@nativescript/vite`'s Angular HMR client calls
7405
+ * `globalThis.__nsRunHmrDispose()` before `__reboot_ng_modules__`,
7406
+ * every registered `dispose(cb)` fires and is handed the same `data`
7407
+ * object the next module evaluation will read from.
7408
+ *
7409
+ * `HmrCacheStore` rides on top of that primitive:
7410
+ *
7411
+ * 1. On construction, it copies any previously-stashed entries out
7412
+ * of `import.meta.hot.data['ns-hmr-cache']` (or whatever
7413
+ * `storageKey` the caller picked) into an in-memory `Map`.
7414
+ * 2. It registers a single `import.meta.hot.dispose` callback that
7415
+ * writes the in-memory `Map` back as a plain object before the
7416
+ * next reboot.
7417
+ * 3. Every `set` re-orders the key to the end of the `Map` (LRU);
7418
+ * when `size > maxEntries`, the oldest entry is evicted. This
7419
+ * stops a long dev session from accumulating unbounded state for
7420
+ * features the developer no longer touches.
7421
+ * 4. It subscribes to a custom HMR event (default
7422
+ * `'ns:cache-invalidate'`) so a Vite plugin or dev server can
7423
+ * push targeted cache evictions — e.g. "the OData schema for
7424
+ * `/safety/forms` changed, drop anything that depends on it".
7425
+ *
7426
+ * In production / `--no-hmr` builds `import.meta.hot` is `undefined`,
7427
+ * the store collapses to a pure in-memory cache that lives for the
7428
+ * lifetime of the process, and the public API is identical so callers
7429
+ * never need to special-case build modes.
7430
+ *
7431
+ * # Why a class and not a plain object
7432
+ *
7433
+ * Encapsulating the LRU bookkeeping behind named methods (`get`,
7434
+ * `set`, `invalidate`, `scope`) lets us evolve the eviction policy
7435
+ * (e.g. add TTLs, weighted entries, structured-clone enforcement)
7436
+ * without touching every call site. The framework wrappers expose
7437
+ * the same surface so app authors learn one API regardless of which
7438
+ * framework they use.
7439
+ */
7440
+ const DEFAULT_MAX_ENTRIES = 256;
7441
+ const DEFAULT_STORAGE_KEY = 'ns-hmr-cache';
7442
+ const DEFAULT_INVALIDATE_EVENT = 'ns:cache-invalidate';
7443
+ /**
7444
+ * Read `import.meta.hot` defensively so the package compiles even
7445
+ * under TypeScript configs that don't extend an `ImportMeta` interface
7446
+ * with a `hot` field. The cast goes through `unknown` so the local
7447
+ * type is the only one in play; `vite/client`-aware apps still get
7448
+ * their own typing on `import.meta.hot` at every call site outside
7449
+ * this module.
7450
+ */
7451
+ function readImportMetaHot() {
7452
+ try {
7453
+ const meta = typeof import.meta !== 'undefined'
7454
+ ? import.meta
7455
+ : undefined;
7456
+ return meta?.hot;
7457
+ }
7458
+ catch {
7459
+ return undefined;
7460
+ }
7461
+ }
7462
+ class HmrCacheStore {
7463
+ /**
7464
+ * @param initialEntries Entries to seed the store with (typically
7465
+ * the previous session's snapshot read from
7466
+ * `import.meta.hot.data`).
7467
+ * @param options See {@link HmrCacheStoreOptions}.
7468
+ */
7469
+ constructor(initialEntries = [], options = {}) {
7470
+ this._map = new Map(initialEntries);
7471
+ const requested = options.maxEntries;
7472
+ this._maxEntries =
7473
+ typeof requested === 'number' && requested > 0
7474
+ ? Math.floor(requested)
7475
+ : 0;
7476
+ this._log = options.log ?? (() => { });
7477
+ // Trim seed if it overshoots the configured ceiling — possible if
7478
+ // a previous session ran with a larger `maxEntries` than this one.
7479
+ this._enforceMaxEntries();
7480
+ }
7481
+ get(key) {
7482
+ if (!this._map.has(key)) {
7483
+ return undefined;
7484
+ }
7485
+ // LRU touch: re-insert so the entry moves to the end of the
7486
+ // insertion-order Map.
7487
+ const value = this._map.get(key);
7488
+ this._map.delete(key);
7489
+ this._map.set(key, value);
7490
+ return value;
7491
+ }
7492
+ set(key, value) {
7493
+ if (this._map.has(key)) {
7494
+ // Delete-then-set keeps insertion order monotonic.
7495
+ this._map.delete(key);
7496
+ }
7497
+ this._map.set(key, value);
7498
+ this._enforceMaxEntries();
7499
+ }
7500
+ has(key) {
7501
+ return this._map.has(key);
7502
+ }
7503
+ delete(key) {
7504
+ this._map.delete(key);
7505
+ }
7506
+ /**
7507
+ * Drop a specific entry, or every entry when `key` is omitted.
7508
+ * Equivalent to {@link delete} (with key) or {@link clear} (without)
7509
+ * — exposed as a single method so callers and event handlers can
7510
+ * forward an optional key without branching.
7511
+ */
7512
+ invalidate(key) {
7513
+ if (key === undefined || key === null) {
7514
+ this.clear();
7515
+ return;
7516
+ }
7517
+ this.delete(key);
7518
+ }
7519
+ /** Drop every cached entry. */
7520
+ clear() {
7521
+ this._map.clear();
7522
+ }
7523
+ /** Total number of cached entries across all scopes. */
7524
+ size() {
7525
+ return this._map.size;
7526
+ }
7527
+ /** Snapshot of every key currently in the cache. */
7528
+ keys() {
7529
+ return Array.from(this._map.keys());
7530
+ }
7531
+ /**
7532
+ * Returns a namespaced view of this store. All keys passed to the
7533
+ * returned object are auto-prefixed with `<prefix>:`. Useful so
7534
+ * each feature module can avoid stomping on neighbours' keys
7535
+ * without repeating the prefix at every call site.
7536
+ *
7537
+ * @example
7538
+ * ```ts
7539
+ * const cache = createDefaultHmrCacheStore();
7540
+ * const submissions = cache.scope('page-my-submissions');
7541
+ * submissions.set('items', [...]); // stored under 'page-my-submissions:items'
7542
+ * ```
7543
+ */
7544
+ scope(prefix) {
7545
+ if (!prefix) {
7546
+ throw new Error('[HmrCacheStore] scope() requires a non-empty prefix');
7547
+ }
7548
+ const fullPrefix = `${prefix}:`;
7549
+ const parent = this;
7550
+ return {
7551
+ prefix: fullPrefix,
7552
+ get(key) {
7553
+ return parent.get(fullPrefix + key);
7554
+ },
7555
+ set(key, value) {
7556
+ parent.set(fullPrefix + key, value);
7557
+ },
7558
+ has(key) {
7559
+ return parent.has(fullPrefix + key);
7560
+ },
7561
+ delete(key) {
7562
+ parent.delete(fullPrefix + key);
7563
+ },
7564
+ clear() {
7565
+ for (const k of parent.keys()) {
7566
+ if (k.startsWith(fullPrefix)) {
7567
+ parent.delete(k);
7568
+ }
7569
+ }
7570
+ },
7571
+ size() {
7572
+ let n = 0;
7573
+ for (const k of parent.keys()) {
7574
+ if (k.startsWith(fullPrefix)) {
7575
+ n++;
7576
+ }
7577
+ }
7578
+ return n;
7579
+ },
7580
+ };
7581
+ }
7582
+ /**
7583
+ * Serialize every entry into a plain object suitable for stashing
7584
+ * on `import.meta.hot.data`. Used by the dispose callback in
7585
+ * {@link createDefaultHmrCacheStore} and re-exported for callers
7586
+ * that want to integrate with another persistence layer (e.g. a
7587
+ * test harness that snapshots between cases).
7588
+ */
7589
+ toObject() {
7590
+ const out = {};
7591
+ for (const [k, v] of this._map.entries()) {
7592
+ out[k] = v;
7593
+ }
7594
+ return out;
7595
+ }
7596
+ _enforceMaxEntries() {
7597
+ if (this._maxEntries <= 0) {
7598
+ return;
7599
+ }
7600
+ while (this._map.size > this._maxEntries) {
7601
+ const oldestKey = this._map.keys().next().value;
7602
+ if (oldestKey === undefined) {
7603
+ return;
7604
+ }
7605
+ this._map.delete(oldestKey);
7606
+ this._log(`[HmrCacheStore] evicted oldest key="${oldestKey}" (size now ${this._map.size}/${this._maxEntries})`);
7607
+ }
7608
+ }
7609
+ }
7610
+ /**
7611
+ * Build an {@link HmrCacheStore} bound to the current module's
7612
+ * `import.meta.hot` context — i.e. the store's data survives HMR
7613
+ * reboots and listens for the `'ns:cache-invalidate'` custom event.
7614
+ *
7615
+ * Caller responsibility: invoke this from the module that "owns" the
7616
+ * cache. `import.meta` is per-module, so the dispose callback will be
7617
+ * registered against whichever module physically calls this function.
7618
+ * In `@nativescript/angular` the canonical owner is
7619
+ * `hmr-cache.service.ts`; in `@nativescript/solid` it would be the
7620
+ * equivalent solid-side module.
7621
+ *
7622
+ * Returns a freshly-constructed store. Callers should treat it as a
7623
+ * singleton — calling this twice from the same module yields two
7624
+ * independent stores, which is almost never what you want.
7625
+ */
7626
+ function createDefaultHmrCacheStore(options = {}) {
7627
+ const storageKey = options.storageKey ?? DEFAULT_STORAGE_KEY;
7628
+ const invalidateEventName = options.invalidateEventName ?? DEFAULT_INVALIDATE_EVENT;
7629
+ const maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
7630
+ const log = options.log ?? (() => { });
7631
+ const hot = readImportMetaHot();
7632
+ // Read previous session's snapshot (if any) and seed the store.
7633
+ const previousSnapshot = (hot?.data?.[storageKey] ?? {});
7634
+ const previousEntries = Object.entries(previousSnapshot);
7635
+ const store = new HmrCacheStore(previousEntries, {
7636
+ maxEntries,
7637
+ storageKey,
7638
+ invalidateEventName,
7639
+ log,
7640
+ });
7641
+ if (hot) {
7642
+ if (previousEntries.length) {
7643
+ log(`[HmrCacheStore] rehydrated ${previousEntries.length} entr${previousEntries.length === 1 ? 'y' : 'ies'} from previous HMR session (storageKey="${storageKey}")`);
7644
+ }
7645
+ // Stash the live store back on dispose so the next reboot finds
7646
+ // exactly what's in memory right now.
7647
+ hot.dispose((data) => {
7648
+ const snapshot = store.toObject();
7649
+ data[storageKey] = snapshot;
7650
+ log(`[HmrCacheStore] dispose stashed ${Object.keys(snapshot).length} entr${Object.keys(snapshot).length === 1 ? 'y' : 'ies'} (storageKey="${storageKey}")`);
7651
+ });
7652
+ // Listen for server-side invalidation events. Vite plugins push
7653
+ // these via `server.ws.send({ type: 'custom', event: 'ns:cache-invalidate', data: { key? } })`.
7654
+ // The HMR client forwards them to `import.meta.hot.on`. If the
7655
+ // runtime doesn't expose `on` (older `@nativescript/ios`), this
7656
+ // is a clean no-op.
7657
+ if (typeof hot.on === 'function') {
7658
+ hot.on(invalidateEventName, (payload) => {
7659
+ const targetKey = payload?.key;
7660
+ store.invalidate(targetKey);
7661
+ log(targetKey
7662
+ ? `[HmrCacheStore] server-side invalidate dropped key="${targetKey}"`
7663
+ : `[HmrCacheStore] server-side invalidate cleared all entries`);
7664
+ });
7665
+ }
7666
+ }
7667
+ return store;
7668
+ }
7669
+
7670
+ /**
7671
+ * Skip the API call your component already paid for last save.
7672
+ *
7673
+ * Inject {@link HmrCacheService} from any Angular component or service
7674
+ * to read and write a per-app key/value cache that **survives the
7675
+ * `__reboot_ng_modules__` cycle** triggered by every HMR file save.
7676
+ * Backed by `@nativescript/ios`'s native `import.meta.hot.data`
7677
+ * (`runtime/HMRSupport.{h,mm}`) and drained via
7678
+ * `@nativescript/vite`'s `globalThis.__nsRunHmrDispose()` hook before
7679
+ * Angular tears down its realm, so the same value the previous
7680
+ * component instance produced is handed straight to the freshly-
7681
+ * instantiated one — no network round-trip, no spinner flash.
7682
+ *
7683
+ * In production / `--no-hmr` builds `import.meta.hot` is `undefined`
7684
+ * and the cache collapses to a plain in-memory object that lives for
7685
+ * the lifetime of the process. The public API is identical, so callers
7686
+ * never need to special-case build modes.
7687
+ *
7688
+ * @example Skip the initial fetch on save
7689
+ * ```ts
7690
+ * import { HmrCacheService } from '@nativescript/angular';
7691
+ *
7692
+ * @Component({...})
7693
+ * export class MyComponent implements OnInit {
7694
+ * private hmrCache = inject(HmrCacheService);
7695
+ *
7696
+ * ngOnInit() {
7697
+ * const cached = this.hmrCache.get<MyResult>('my-feature:items');
7698
+ * if (cached) {
7699
+ * this.applyResult(cached);
7700
+ * return;
7701
+ * }
7702
+ * this.api.load().subscribe((result) => {
7703
+ * this.hmrCache.set('my-feature:items', result);
7704
+ * this.applyResult(result);
7705
+ * });
7706
+ * }
7707
+ * }
7708
+ * ```
7709
+ *
7710
+ * @example Namespaced via {@link scope}
7711
+ * ```ts
7712
+ * private cache = inject(HmrCacheService).scope('page-my-submissions');
7713
+ * // …
7714
+ * this.cache.set('items', items); // → 'page-my-submissions:items'
7715
+ * this.cache.get('items'); // ← 'page-my-submissions:items'
7716
+ * ```
7717
+ *
7718
+ * @example Server-side invalidation from a Vite plugin
7719
+ * ```ts
7720
+ * // vite.config.ts
7721
+ * export default defineConfig({
7722
+ * plugins: [
7723
+ * {
7724
+ * name: 'my-schema-watcher',
7725
+ * configureServer(server) {
7726
+ * server.watcher.on('change', (path) => {
7727
+ * if (path.endsWith('schema.json')) {
7728
+ * server.ws.send({
7729
+ * type: 'custom',
7730
+ * event: 'ns:cache-invalidate',
7731
+ * data: { key: 'my-feature:items' },
7732
+ * });
7733
+ * }
7734
+ * });
7735
+ * },
7736
+ * },
7737
+ * ],
7738
+ * });
7739
+ * ```
7740
+ *
7741
+ * Memory ceiling: the cache LRU-evicts at 256 entries by default. Pass
7742
+ * a custom ceiling via {@link configureHmrCache} if your app churns
7743
+ * through more keys than that in a typical dev session, or set `0` for
7744
+ * unlimited (unbounded growth — only safe for short-lived dev work).
7745
+ *
7746
+ * @see HmrCacheStore — the framework-agnostic engine. Stable enough to
7747
+ * lift into `@nativescript/solid` / other framework bindings without
7748
+ * modification.
7749
+ */
7750
+ class HmrCacheService {
7751
+ constructor() {
7752
+ this._store = getOrCreateSharedStore();
7753
+ /**
7754
+ * `true` when `import.meta.hot` is wired (i.e. NativeScript Vite HMR
7755
+ * is active and `@nativescript/ios` is recent enough to expose
7756
+ * `import.meta.hot.data`). `false` in production / `--no-hmr` /
7757
+ * legacy webpack builds.
7758
+ *
7759
+ * Most callers should NOT branch on this — the public API works
7760
+ * identically in both cases. Use it only when you want to opt OUT
7761
+ * of caching in production (e.g. always fetch fresh data when not
7762
+ * developing).
7763
+ */
7764
+ this.isHmr = isAngularHmrEnabled() && hasImportMetaHot();
7765
+ }
7766
+ get(key) {
7767
+ return this._store.get(key);
7768
+ }
7769
+ set(key, value) {
7770
+ this._store.set(key, value);
7771
+ }
7772
+ has(key) {
7773
+ return this._store.has(key);
7774
+ }
7775
+ delete(key) {
7776
+ this._store.delete(key);
7777
+ }
7778
+ /**
7779
+ * Drop a single entry, or every entry when `key` is omitted. Same
7780
+ * shape as the `'ns:cache-invalidate'` HMR-event payload the store
7781
+ * listens for, so application code can call this directly to mirror
7782
+ * a server-side eviction.
7783
+ */
7784
+ invalidate(key) {
7785
+ this._store.invalidate(key);
7786
+ }
7787
+ /** Drop every cached entry. Equivalent to `invalidate()` with no key. */
7788
+ clear() {
7789
+ this._store.clear();
7790
+ }
7791
+ /** Total number of entries across every scope. */
7792
+ size() {
7793
+ return this._store.size();
7794
+ }
7795
+ /** Snapshot of every key currently cached. Useful for debug overlays. */
7796
+ keys() {
7797
+ return this._store.keys();
7798
+ }
7799
+ /**
7800
+ * Returns a namespaced view of the cache. All `get` / `set` /
7801
+ * `has` / `delete` calls on the returned object are auto-prefixed
7802
+ * with `<scopeName>:`. Recommended over global keys so feature
7803
+ * modules don't accidentally collide.
7804
+ *
7805
+ * @example
7806
+ * ```ts
7807
+ * private cache = inject(HmrCacheService).scope('page-my-submissions');
7808
+ * // …
7809
+ * this.cache.set('items', items); // → 'page-my-submissions:items'
7810
+ * ```
7811
+ */
7812
+ scope(scopeName) {
7813
+ return this._store.scope(scopeName);
7814
+ }
7815
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: HmrCacheService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
7816
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: HmrCacheService, providedIn: 'root' }); }
7817
+ }
7818
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: HmrCacheService, decorators: [{
7819
+ type: Injectable,
7820
+ args: [{ providedIn: 'root' }]
7821
+ }] });
7822
+ /**
7823
+ * Override the default cache configuration. Must be called BEFORE the
7824
+ * first injection of {@link HmrCacheService} (i.e. before Angular
7825
+ * bootstrap, or as the very first statement in `main.ts`); otherwise
7826
+ * the call is a no-op because the singleton store has already been
7827
+ * built with the previous (or default) options.
7828
+ *
7829
+ * Typical use case: bumping `maxEntries` for a large multi-feature
7830
+ * monorepo dev session, or pointing a custom `invalidateEventName` at
7831
+ * a Vite plugin that prefixes its events with the project name.
7832
+ *
7833
+ * Returns `true` if the configuration was applied, `false` if the
7834
+ * store had already been instantiated by an earlier injection.
7835
+ */
7836
+ function configureHmrCache(options) {
7837
+ if (sharedStore !== null) {
7838
+ return false;
7839
+ }
7840
+ pendingOptions = options;
7841
+ return true;
7842
+ }
7843
+ /**
7844
+ * Read-only access to the underlying {@link HmrCacheStore}. Exposed
7845
+ * for advanced integrations that want to reuse the LRU + dispose +
7846
+ * server-side-invalidate plumbing without going through Angular's
7847
+ * dependency injection (e.g. a non-component utility that's loaded
7848
+ * before the Angular platform has bootstrapped). Application code
7849
+ * should prefer {@link HmrCacheService}.
7850
+ */
7851
+ function getHmrCacheStore() {
7852
+ return getOrCreateSharedStore();
7853
+ }
7854
+ let sharedStore = null;
7855
+ let pendingOptions = null;
7856
+ function getOrCreateSharedStore() {
7857
+ if (sharedStore !== null) {
7858
+ return sharedStore;
7859
+ }
7860
+ const options = {
7861
+ log: (msg) => {
7862
+ // Keep cache diagnostics on the same channel as other HMR
7863
+ // helpers so devs can grep one trace category and see the full
7864
+ // picture during a save cycle. NativeScriptDebug.bootstrapLog
7865
+ // is the conventional sink for HMR-adjacent lifecycle logs.
7866
+ try {
7867
+ NativeScriptDebug.bootstrapLog(msg);
7868
+ }
7869
+ catch {
7870
+ // Defensive: never crash the cache if the trace channel is
7871
+ // unavailable (e.g. tests that import this file in isolation).
7872
+ }
7873
+ },
7874
+ ...pendingOptions,
7875
+ };
7876
+ sharedStore = createDefaultHmrCacheStore(options);
7877
+ pendingOptions = null;
7878
+ return sharedStore;
7879
+ }
7880
+ function hasImportMetaHot() {
7881
+ try {
7882
+ const meta = typeof import.meta !== 'undefined'
7883
+ ? import.meta
7884
+ : undefined;
7885
+ return !!meta?.hot;
7886
+ }
7887
+ catch {
7888
+ return false;
7889
+ }
7890
+ }
7891
+
7363
7892
  class BaseValueAccessor {
7364
7893
  constructor(view) {
7365
7894
  this.view = view;
@@ -10188,5 +10717,5 @@ function provideNativeScriptNgZone(options) {
10188
10717
  * Generated bundle index. Do not edit.
10189
10718
  */
10190
10719
 
10191
- export { APP_ROOT_VIEW, ActionBarComponent, ActionBarScope, ActionItemDirective, AndroidFilterComponent, AppHostAsyncView, AppHostView, AppleFilterComponent, BasePortalOutlet, BaseValueAccessor, COMMON_PROVIDERS, CdkPortal, CdkPortalOutlet, CheckedValueAccessor, CommentNode, ComponentPortal, DEVICE, DISABLE_ROOT_VIEW_HANDLING, DateValueAccessor, DetachedLoader, DomPortal, ENABLE_REUSABE_VIEWS, EmulatedRenderer, FrameDirective, FramePageComponent, FramePageModule, FrameService, IOSFilterComponent, InjectableAnimationEngine, InvisibleNode, ItemContext, ListViewComponent, ModalDialogParams, ModalDialogService, NAMESPACE_FILTERS, NATIVESCRIPT_MODULE_PROVIDERS, NATIVESCRIPT_MODULE_STATIC_PROVIDERS, NATIVESCRIPT_ROOT_MODULE_ID, NATIVE_DIALOG_DATA, NATIVE_DIALOG_DEFAULT_OPTIONS, NSEmptyOutletComponent, NSFileSystem, NSLocationStrategy, NSRouteReuseStrategy, NSRouterLink, NSRouterLinkActive, NativeDialog, NativeDialogCloseDirective, NativeDialogConfig, NativeDialogModule, NativeDialogRef, NativeDialog as NativeDialogService, NativeModalRef, NativeScriptAnimationDriver, NativeScriptAnimationPlayer, NativeScriptAnimationsModule, NativeScriptCommonModule, NativeScriptDocument, NativeScriptDomPortalOutlet, NativeScriptFormsModule, NativeScriptHttpClientModule, NativeScriptLoadingService, NativeScriptModule, NativeScriptNgSafeEvent, NativeScriptNgZone, NativeScriptRendererFactory, NativeScriptRendererHelperService, NativeScriptRouterModule, NativeScriptSanitizer, NativescriptXhrFactory, NavigationButtonDirective, NgViewRef, NsHttpBackEnd, NsTemplatedItem, NumberValueAccessor, Outlet, PAGE_FACTORY, PREVENT_CHANGE_EVENTS_DURING_CD, PREVENT_SPECIFIC_EVENTS_DURING_CD, PageDirective, PageRoute, PageRouterOutlet, PageService, PlatformNamespaceFilter, Portal, PortalModule, RootCompositeModule, RootViewProxy, RouterExtensions, START_PATH, SelectedIndexValueAccessor, TEMPLATED_ITEMS_COMPONENT, TabViewDirective, TabViewItemDirective, TemplateKeyDirective, TemplatePortal, TextNode, TextValueAccessor, TimeValueAccessor, VisionOSFilterComponent, bootstrapApplication, createKeyframeAnimation, customFrameComponentFactory, customFrameDirectiveFactory, customPageFactory, customPageFactoryFromFrame, dashCaseToCamelCase, defaultNavOptions, defaultPageFactory, defaultPageFactoryProvider, detachViewFromParent, disableRootViewHanding, errorHandler, extractSingleViewRecursive, frameMeta, generateDetachedLoader, generateFallbackRootView, generateNativeScriptView, generateRandomId, generateRootLayoutAndProxy, getAngularHmrRestoringRoute, getFirstNativeLikeView, getItemViewRoot, getSingleViewRecursive, getViewClass, getViewMeta, instantiateDefaultStyleNormalizer, instantiateSupportedAnimationDriver, isAngularHmrRestoringRoute, isBlank, isContentView, isDetachedElement, isInvisibleNode, isJsObject, isKnownView, isLayout, isListLikeIterable, isPresent, isView, onAfterLivesync, onBeforeLivesync, once, platformNativeScript, platformNativeScriptDynamic, postAngularBootstrap$, preAngularDisposal$, provideLocationStrategy, provideNativeScriptHttpClient, provideNativeScriptNgZone, provideNativeScriptRouter, registerElement, registerNativeScriptViewComponents, rootRoute, runNativeScriptAngularApp, throwIfAlreadyLoaded, throwNoPortalAttachedError, throwNullPortalError, throwNullPortalOutletError, throwPortalAlreadyAttachedError, throwPortalOutletAlreadyDisposedError, throwUnknownPortalTypeError, COMPONENT_VARIABLE as ɵCOMPONENT_VARIABLE, CONTENT_ATTR as ɵCONTENT_ATTR, HOST_ATTR as ɵHOST_ATTR, NativeScriptDebug as ɵNativeScriptAngularDebug, viewUtil as ɵViewUtil, actionBarMeta as ɵactionBarMeta, elementMap as ɵelementMap, isActionItem as ɵisActionItem, isNavigationButton as ɵisNavigationButton };
10720
+ export { APP_ROOT_VIEW, ActionBarComponent, ActionBarScope, ActionItemDirective, AndroidFilterComponent, AppHostAsyncView, AppHostView, AppleFilterComponent, BasePortalOutlet, BaseValueAccessor, COMMON_PROVIDERS, CdkPortal, CdkPortalOutlet, CheckedValueAccessor, CommentNode, ComponentPortal, DEVICE, DISABLE_ROOT_VIEW_HANDLING, DateValueAccessor, DetachedLoader, DomPortal, ENABLE_REUSABE_VIEWS, EmulatedRenderer, FrameDirective, FramePageComponent, FramePageModule, FrameService, HmrCacheService, HmrCacheStore, IOSFilterComponent, InjectableAnimationEngine, InvisibleNode, ItemContext, ListViewComponent, ModalDialogParams, ModalDialogService, NAMESPACE_FILTERS, NATIVESCRIPT_MODULE_PROVIDERS, NATIVESCRIPT_MODULE_STATIC_PROVIDERS, NATIVESCRIPT_ROOT_MODULE_ID, NATIVE_DIALOG_DATA, NATIVE_DIALOG_DEFAULT_OPTIONS, NSEmptyOutletComponent, NSFileSystem, NSLocationStrategy, NSRouteReuseStrategy, NSRouterLink, NSRouterLinkActive, NativeDialog, NativeDialogCloseDirective, NativeDialogConfig, NativeDialogModule, NativeDialogRef, NativeDialog as NativeDialogService, NativeModalRef, NativeScriptAnimationDriver, NativeScriptAnimationPlayer, NativeScriptAnimationsModule, NativeScriptCommonModule, NativeScriptDocument, NativeScriptDomPortalOutlet, NativeScriptFormsModule, NativeScriptHttpClientModule, NativeScriptLoadingService, NativeScriptModule, NativeScriptNgSafeEvent, NativeScriptNgZone, NativeScriptRendererFactory, NativeScriptRendererHelperService, NativeScriptRouterModule, NativeScriptSanitizer, NativescriptXhrFactory, NavigationButtonDirective, NgViewRef, NsHttpBackEnd, NsTemplatedItem, NumberValueAccessor, Outlet, PAGE_FACTORY, PREVENT_CHANGE_EVENTS_DURING_CD, PREVENT_SPECIFIC_EVENTS_DURING_CD, PageDirective, PageRoute, PageRouterOutlet, PageService, PlatformNamespaceFilter, Portal, PortalModule, RootCompositeModule, RootViewProxy, RouterExtensions, START_PATH, SelectedIndexValueAccessor, TEMPLATED_ITEMS_COMPONENT, TabViewDirective, TabViewItemDirective, TemplateKeyDirective, TemplatePortal, TextNode, TextValueAccessor, TimeValueAccessor, VisionOSFilterComponent, bootstrapApplication, configureHmrCache, createDefaultHmrCacheStore, createKeyframeAnimation, customFrameComponentFactory, customFrameDirectiveFactory, customPageFactory, customPageFactoryFromFrame, dashCaseToCamelCase, defaultNavOptions, defaultPageFactory, defaultPageFactoryProvider, detachViewFromParent, disableRootViewHanding, errorHandler, extractSingleViewRecursive, frameMeta, generateDetachedLoader, generateFallbackRootView, generateNativeScriptView, generateRandomId, generateRootLayoutAndProxy, getAngularHmrRestoringRoute, getFirstNativeLikeView, getHmrCacheStore, getItemViewRoot, getSingleViewRecursive, getViewClass, getViewMeta, instantiateDefaultStyleNormalizer, instantiateSupportedAnimationDriver, isAngularHmrRestoringRoute, isBlank, isContentView, isDetachedElement, isInvisibleNode, isJsObject, isKnownView, isLayout, isListLikeIterable, isPresent, isView, onAfterLivesync, onBeforeLivesync, once, platformNativeScript, platformNativeScriptDynamic, postAngularBootstrap$, preAngularDisposal$, provideLocationStrategy, provideNativeScriptHttpClient, provideNativeScriptNgZone, provideNativeScriptRouter, registerElement, registerNativeScriptViewComponents, rootRoute, runNativeScriptAngularApp, throwIfAlreadyLoaded, throwNoPortalAttachedError, throwNullPortalError, throwNullPortalOutletError, throwPortalAlreadyAttachedError, throwPortalOutletAlreadyDisposedError, throwUnknownPortalTypeError, COMPONENT_VARIABLE as ɵCOMPONENT_VARIABLE, CONTENT_ATTR as ɵCONTENT_ATTR, HOST_ATTR as ɵHOST_ATTR, NativeScriptDebug as ɵNativeScriptAngularDebug, viewUtil as ɵViewUtil, actionBarMeta as ɵactionBarMeta, elementMap as ɵelementMap, isActionItem as ɵisActionItem, isNavigationButton as ɵisNavigationButton };
10192
10721
  //# sourceMappingURL=nativescript-angular.mjs.map