{"version":3,"file":"cdk-ssr.mjs","sources":["../../../../libs/cdk/ssr/src/lib/config.ts","../../../../libs/cdk/ssr/src/lib/platform.ts","../../../../libs/cdk/ssr/src/lib/hydration-tracker.ts","../../../../libs/cdk/ssr/src/cdk-ssr.ts"],"sourcesContent":["import { InjectionToken, Provider } from '@angular/core';\n\n/**\n * Configuration for the `HydrationTracker` service.\n */\nexport interface HydrationTrackerConfig {\n  /**\n   * The timeout in milliseconds after which the hydration tracker will consider the application hydrated.\n   * If not provided, defaults to 10 seconds (10000 milliseconds).\n   */\n  timeout?: number;\n\n  /**\n   * Whether to log the hydration tracker events to the console.\n   * If not provided, defaults to false.\n   */\n  logging?: boolean;\n}\n\nconst defaultConfig: HydrationTrackerConfig = {\n  timeout: 10000,\n  logging: false,\n};\n\n/**\n * Injection token for the `HydrationTracker` service configuration.\n */\nexport const HYDRATION_TRACKER_CONFIG_TOKEN =\n  new InjectionToken<HydrationTrackerConfig>('HYDRATION_TRACKER_CONFIG_TOKEN', {\n    providedIn: 'root',\n    factory: () => defaultConfig,\n  });\n\n/**\n * Provides a configuration object for the `HydrationTracker` service.\n *\n * @param config - The configuration object.\n *\n * Example usage:\n * ```ts\n * import { provideHydrationTracker } from '@rx-angular/cdk/ssr';\n *\n * const appConfig: ApplicationConfig = {\n *   providers: [provideHydrationTracker({ timeout: 10000 })],\n * };\n * ```\n */\nexport function provideHydrationTracker(\n  config: HydrationTrackerConfig = defaultConfig,\n): Provider {\n  return {\n    provide: HYDRATION_TRACKER_CONFIG_TOKEN,\n    useValue: { ...defaultConfig, ...config },\n  } satisfies Provider;\n}\n","import { isPlatformBrowser, isPlatformServer } from '@angular/common';\nimport { DOCUMENT, inject, InjectionToken, PLATFORM_ID } from '@angular/core';\n\n/**\n * An injection token that provides information about the current platform.\n *\n * It provides the following information:\n * - `isServer`: Whether the current platform is the server.\n * - `isBrowser`: Whether the current platform is the browser.\n * - `isServerRenderer`: Whether the current platform is the browser and the application was server-side rendered.\n */\nexport const PLATFORM = new InjectionToken<{\n  isServer: boolean;\n  isBrowser: boolean;\n  isServerRendered: boolean;\n}>('PLATFORM', {\n  providedIn: 'platform',\n  factory: () => {\n    const platformId = inject(PLATFORM_ID);\n    const document = inject(DOCUMENT);\n\n    const isServer = isPlatformServer(platformId);\n    const isBrowser = isPlatformBrowser(platformId);\n    const isServerRendered = isBrowser && !!document.getElementById('ng-state');\n\n    return { isServer, isBrowser, isServerRendered };\n  },\n});\n","import { inject, Injectable, NgZone, OnDestroy, signal } from '@angular/core';\nimport { toObservable } from '@angular/core/rxjs-interop';\nimport { HYDRATION_TRACKER_CONFIG_TOKEN } from './config';\nimport { PLATFORM } from './platform';\n\n/**\n * A high-performance utility to track application hydration status using a MutationObserver,\n * with a timeout safety net.\n *\n * It provides a signal `isFullyHydrated` that becomes true once all components are\n * hydrated or after a configurable timeout (default: 10 seconds).\n *\n * Disclaimer: The service only runs in the browser and is not available on the server.\n */\n@Injectable({ providedIn: 'root' })\nexport class HydrationTracker implements OnDestroy {\n  private config = inject(HYDRATION_TRACKER_CONFIG_TOKEN);\n  private platform = inject(PLATFORM);\n  private ngZone = inject(NgZone);\n  private observer: MutationObserver | null = null;\n  private timeoutId: any = null; // Stores the setTimeout ID\n\n  /**\n   * A reactive signal that emits `true` when the application is fully hydrated.\n   */\n  readonly isFullyHydrated = signal(false);\n\n  /**\n   * An observable that emits `true` when the application is fully hydrated.\n   */\n  readonly isFullyHydrated$ = toObservable(this.isFullyHydrated);\n\n  constructor() {\n    if (this.platform.isServerRendered) {\n      this.initializeObserver();\n    } else if (this.platform.isBrowser) {\n      this.isFullyHydrated.set(true);\n    }\n  }\n\n  private initializeObserver(): void {\n    const unhydratedElements = this.getUnhydratedElements();\n    let unhydratedCount = unhydratedElements.length;\n\n    if (unhydratedCount === 0) {\n      this.isFullyHydrated.set(true);\n      if (this.config.logging) {\n        console.log(\n          '[HydrationTracker] ✅ Application was already hydrated on initialization.',\n        );\n      }\n      return;\n    }\n\n    this.observer = new MutationObserver((mutations) => {\n      for (const mutation of mutations) {\n        if (\n          mutation.type === 'attributes' &&\n          mutation.attributeName === 'ngh'\n        ) {\n          const element = mutation.target as Element;\n          if (!element.hasAttribute('ngh')) {\n            unhydratedCount--;\n          }\n        }\n      }\n\n      if (unhydratedCount <= 0) {\n        // Hydration finished normally, so we don't need the timeout.\n        this.completeHydration(false);\n      }\n    });\n\n    unhydratedElements.forEach((element) => {\n      this.ngZone.runOutsideAngular(() => {\n        this.observer?.observe(element, {\n          attributes: true,\n          attributeFilter: ['ngh'],\n        });\n      });\n    });\n\n    if (this.config.timeout) {\n      // Set a timeout as a safety net.\n      this.timeoutId = this.ngZone.runOutsideAngular(() =>\n        setTimeout(() => {\n          this.completeHydration(true); // `true` indicates it was a timeout\n        }, this.config.timeout),\n      );\n    }\n  }\n\n  private getUnhydratedElements(): Element[] {\n    return Array.from(document.body.querySelectorAll('[ngh]'));\n  }\n\n  private completeHydration(timedOut: boolean): void {\n    // If this function is running, we must clear any pending timeout.\n    if (this.timeoutId) {\n      clearTimeout(this.timeoutId);\n      this.timeoutId = null;\n    }\n\n    this.isFullyHydrated.set(true);\n\n    if (timedOut) {\n      if (this.config.logging) {\n        console.warn(\n          `[HydrationTracker] 🟡 Hydration check timed out after ${this.config.timeout} milliseconds. Forcing completion.`,\n        );\n      }\n    } else {\n      if (this.config.logging) {\n        console.log('[HydrationTracker] ✅ Application is now fully hydrated.');\n      }\n    }\n\n    // Disconnect the observer to free up resources.\n    this.observer?.disconnect();\n    this.observer = null;\n  }\n\n  ngOnDestroy(): void {\n    // Ensure both the observer and the timeout are cleaned up.\n    this.observer?.disconnect();\n    if (this.timeoutId) {\n      clearTimeout(this.timeoutId);\n    }\n  }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}