@dreamsengine/dreams-ad-engine 0.2.1 → 0.3.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dreamsengine/dreams-ad-engine",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "license": "GPL-3.0",
6
6
  "main": "./dist/dreams-ad-engine.js",
@@ -0,0 +1,45 @@
1
+ import type { AdBlockConfig, AdBlockDetectionResult } from "./adblock.types";
2
+ declare global {
3
+ interface Window {
4
+ adBlockDetected?: boolean;
5
+ }
6
+ }
7
+ export declare class AdBlockDetector {
8
+ private static config;
9
+ private static detected;
10
+ private static detecting;
11
+ /**
12
+ * Configure the ad block detector
13
+ */
14
+ static configure(config: AdBlockConfig): void;
15
+ /**
16
+ * Check if ad blocker is detected (cached result)
17
+ */
18
+ static isBlocked(): boolean;
19
+ /**
20
+ * Run ad blocker detection
21
+ */
22
+ static detect(): Promise<AdBlockDetectionResult>;
23
+ /**
24
+ * Initialize detection and apply body class if blocked
25
+ */
26
+ static init(): Promise<boolean>;
27
+ /**
28
+ * Reset detection state
29
+ */
30
+ static reset(): void;
31
+ private static runDetection;
32
+ /**
33
+ * Method 1: Check if googletag loaded properly
34
+ */
35
+ private static testGoogleTag;
36
+ /**
37
+ * Method 2: Bait element detection
38
+ * Ad blockers often hide elements with common ad class names
39
+ */
40
+ private static testBaitElement;
41
+ /**
42
+ * Method 3: Fetch a known ad resource
43
+ */
44
+ private static testFetch;
45
+ }
@@ -0,0 +1,14 @@
1
+ export interface AdBlockDetectionResult {
2
+ blocked: boolean;
3
+ method: "googletag" | "bait" | "fetch" | "none";
4
+ }
5
+ export interface AdBlockConfig {
6
+ /** Enable detection on load. Default: true */
7
+ enabled?: boolean;
8
+ /** Add body class when detected. Default: true */
9
+ addBodyClass?: boolean;
10
+ /** Body class name. Default: "ad-blocker-detected" */
11
+ bodyClass?: string;
12
+ /** Timeout for detection methods in ms. Default: 1000 */
13
+ timeout?: number;
14
+ }
@@ -0,0 +1,2 @@
1
+ export { AdBlockDetector } from "./adblock.service";
2
+ export type { AdBlockConfig, AdBlockDetectionResult } from "./adblock.types";
@@ -16,7 +16,9 @@ export interface AdConfigInit {
16
16
  bidTimeout?: number;
17
17
  defaultLazyLoad?: LazyLoadConfig;
18
18
  slots?: Record<string, SlotConfig>;
19
+ /** Set to true to allow re-initialization (overwrites existing config) */
20
+ force?: boolean;
19
21
  }
20
- export interface AdConfigData extends Required<Omit<AdConfigInit, "slots">> {
22
+ export interface AdConfigData extends Required<Omit<AdConfigInit, "slots" | "force">> {
21
23
  slots: Record<string, SlotConfig>;
22
24
  }
@@ -2,12 +2,26 @@ import { LitElement } from "lit";
2
2
  import type { TemplateResult } from "lit/html.js";
3
3
  import "../types/interfaces";
4
4
  import { DreamsAdMapping, DreamsAdTargeting } from "../types/interfaces";
5
+ import "../../skeleton/skeleton.component";
5
6
  export declare class DreamsAdComponent extends LitElement {
6
7
  #private;
7
8
  static styles: import("lit").CSSResult;
8
9
  static initialized: boolean;
9
10
  static old_url: string;
10
11
  static initialized_aps: boolean;
12
+ static navigationListenersAttached: boolean;
13
+ static servicesWereAlreadyEnabled: boolean;
14
+ static lazyLoadConfigured: boolean;
15
+ private adSlot;
16
+ private slotRenderHandler;
17
+ /**
18
+ * Handle SPA navigation - destroys all slots and clears targeting cache
19
+ */
20
+ private static _handleNavigation;
21
+ /**
22
+ * Set up global navigation listeners for SPA support
23
+ */
24
+ private static _setupNavigationListeners;
11
25
  networkId: string;
12
26
  adUnit: string;
13
27
  divId: string;
@@ -31,7 +45,10 @@ export declare class DreamsAdComponent extends LitElement {
31
45
  bidTimeout: number;
32
46
  title: string;
33
47
  adLoaded: boolean;
48
+ trackViewability: boolean;
49
+ showSkeleton: boolean;
34
50
  connectedCallback(): void;
51
+ disconnectedCallback(): void;
35
52
  firstUpdated(): Promise<void>;
36
53
  protected render(): TemplateResult;
37
54
  }
@@ -1 +1 @@
1
- export * from './components/ad.component';
1
+ export * from "./components/ad.component";
@@ -1,6 +1,7 @@
1
1
  export interface Googletag {
2
2
  cmd: Array<() => void>;
3
3
  pubads: () => PubAdsService;
4
+ pubadsReady?: boolean;
4
5
  defineSlot: (adUnitPath: string, size: Array<number> | Array<Array<number>>, divId: string) => Slot;
5
6
  display: (divId: string) => void;
6
7
  enableServices: () => void;
@@ -27,9 +28,12 @@ interface LazyLoadObject {
27
28
  interface PubAdsService {
28
29
  disableInitialLoad: () => void;
29
30
  enableSingleRequest: () => void;
30
- refresh: (slots?: Slot[]) => void;
31
+ refresh: (slots?: Slot[], options?: {
32
+ changeCorrelator?: boolean;
33
+ }) => void;
31
34
  addService: (service: ServiceType) => Slot;
32
35
  addEventListener: (eventType: string, handler: (event: any) => void) => void;
36
+ removeEventListener: (eventType: string, handler: (event: any) => void) => void;
33
37
  setCentering: (centerAds: boolean) => void;
34
38
  enableLazyLoad: (config: LazyLoadObject) => void;
35
39
  }
@@ -1,3 +1,9 @@
1
1
  export * from "./dreamsAdEngine/";
2
2
  export * from "./targeting/";
3
3
  export * from "./config/";
4
+ export * from "./viewability/";
5
+ export * from "./skeleton/";
6
+ export * from "./adblock/";
7
+ export * from "./refresh/";
8
+ export * from "./logging/";
9
+ export * from "./sticky/";
@@ -0,0 +1,2 @@
1
+ export { Logger } from "./logger";
2
+ export type { LoggerConfig } from "./logger";
@@ -0,0 +1,56 @@
1
+ export interface LoggerConfig {
2
+ /** Enable logging. Default: auto (dev only) */
3
+ enabled?: boolean | "auto";
4
+ /** Log prefix. Default: "[DreamsAdEngine]" */
5
+ prefix?: string;
6
+ /** Enable verbose logging. Default: false */
7
+ verbose?: boolean;
8
+ }
9
+ /**
10
+ * Production-aware logger for Dreams Ad Engine
11
+ */
12
+ export declare class Logger {
13
+ private static config;
14
+ /**
15
+ * Configure the logger
16
+ */
17
+ static configure(config: LoggerConfig): void;
18
+ /**
19
+ * Log info message
20
+ */
21
+ static log(message: string, ...args: unknown[]): void;
22
+ /**
23
+ * Log warning message
24
+ */
25
+ static warn(message: string, ...args: unknown[]): void;
26
+ /**
27
+ * Log error message (always logs in production, but less verbose)
28
+ */
29
+ static error(message: string, ...args: unknown[]): void;
30
+ /**
31
+ * Log verbose/debug message (only when verbose is enabled)
32
+ */
33
+ static debug(message: string, ...args: unknown[]): void;
34
+ /**
35
+ * Log a table (useful for metrics)
36
+ */
37
+ static table(data: unknown[]): void;
38
+ /**
39
+ * Group logs together
40
+ */
41
+ static group(label: string): void;
42
+ /**
43
+ * End log group
44
+ */
45
+ static groupEnd(): void;
46
+ /**
47
+ * Time a operation
48
+ */
49
+ static time(label: string): void;
50
+ /**
51
+ * End timing
52
+ */
53
+ static timeEnd(label: string): void;
54
+ private static shouldLog;
55
+ private static isProduction;
56
+ }
@@ -0,0 +1,2 @@
1
+ export { RefreshManager } from "./refresh.service";
2
+ export type { RefreshConfig, RefreshEvent } from "./refresh.types";
@@ -0,0 +1,46 @@
1
+ import type { RefreshConfig } from "./refresh.types";
2
+ declare global {
3
+ interface Window {
4
+ DreamsBlockedRefresh?: boolean;
5
+ lastAdRefresh?: number;
6
+ isTabVisible?: boolean;
7
+ }
8
+ }
9
+ export declare class RefreshManager {
10
+ private static config;
11
+ private static refreshTimer;
12
+ private static running;
13
+ /**
14
+ * Configure the refresh manager
15
+ */
16
+ static configure(config: RefreshConfig): void;
17
+ /**
18
+ * Start auto-refresh loop
19
+ */
20
+ static start(): void;
21
+ /**
22
+ * Stop auto-refresh loop
23
+ */
24
+ static stop(): void;
25
+ /**
26
+ * Manually trigger a refresh (respects safeguards)
27
+ */
28
+ static refresh(slots?: any[]): boolean;
29
+ /**
30
+ * Block refresh (e.g., during user interaction)
31
+ */
32
+ static block(): void;
33
+ /**
34
+ * Unblock refresh
35
+ */
36
+ static unblock(): void;
37
+ /**
38
+ * Check if refresh is currently blocked
39
+ */
40
+ static isBlocked(): boolean;
41
+ private static setupVisibilityTracking;
42
+ private static scheduleRefresh;
43
+ private static executeRefresh;
44
+ private static safeRefresh;
45
+ private static dispatchEvent;
46
+ }
@@ -0,0 +1,18 @@
1
+ export interface RefreshConfig {
2
+ /** Enable auto-refresh. Default: false */
3
+ enabled?: boolean;
4
+ /** Refresh interval in ms. Minimum 30000 (30s). Default: 60000 */
5
+ interval?: number;
6
+ /** Skip refresh when tab is hidden. Default: true */
7
+ checkVisibility?: boolean;
8
+ /** Disable on single-post pages. Default: true */
9
+ disableOnSinglePost?: boolean;
10
+ /** CSS selector for single-post detection. Default: "body.single" */
11
+ singlePostSelector?: string;
12
+ }
13
+ export interface RefreshEvent {
14
+ type: "refresh" | "skipped";
15
+ reason?: "hidden" | "blocked" | "throttled";
16
+ slots: number;
17
+ timestamp: number;
18
+ }
@@ -0,0 +1 @@
1
+ export { DreamsAdSkeleton, getSkeletonDimensions } from "./skeleton.component";
@@ -0,0 +1,20 @@
1
+ import { LitElement } from "lit";
2
+ /**
3
+ * Skeleton loader component for ad placeholders
4
+ * Displays shimmer animation while ad loads
5
+ */
6
+ export declare class DreamsAdSkeleton extends LitElement {
7
+ static styles: import("lit").CSSResult;
8
+ width: number;
9
+ height: number;
10
+ showLabel: boolean;
11
+ label: string;
12
+ render(): import("lit").TemplateResult<1>;
13
+ }
14
+ /**
15
+ * Get skeleton dimensions based on slot type and viewport width
16
+ */
17
+ export declare function getSkeletonDimensions(slotType: string, viewportWidth: number): {
18
+ width: number;
19
+ height: number;
20
+ };
@@ -0,0 +1,2 @@
1
+ export { StickyManager } from "./sticky.service";
2
+ export type { StickyConfig, StickyMetrics } from "./sticky.types";
@@ -0,0 +1,38 @@
1
+ import type { StickyConfig, StickyMetrics } from "./sticky.types";
2
+ export declare class StickyManager {
3
+ private static config;
4
+ private static stickyAds;
5
+ private static lastScrollTime;
6
+ /**
7
+ * Configure the sticky manager
8
+ */
9
+ static configure(config: StickyConfig): void;
10
+ /**
11
+ * Check if a position supports sticky
12
+ */
13
+ static isStickyPosition(position: string): boolean;
14
+ /**
15
+ * Enable sticky behavior for an ad element
16
+ */
17
+ static enable(container: HTMLElement, adId: string, position: string): boolean;
18
+ /**
19
+ * Disable sticky behavior for an ad
20
+ */
21
+ static disable(adId: string): void;
22
+ /**
23
+ * Get metrics for a sticky ad
24
+ */
25
+ static getMetrics(adId: string): StickyMetrics | null;
26
+ /**
27
+ * Get all sticky metrics
28
+ */
29
+ static getAllMetrics(): StickyMetrics[];
30
+ /**
31
+ * Reset all sticky ads
32
+ */
33
+ static reset(): void;
34
+ private static getTopOffset;
35
+ private static handleScroll;
36
+ private static checkSticky;
37
+ private static dispatchEvent;
38
+ }
@@ -0,0 +1,23 @@
1
+ export interface StickyConfig {
2
+ /** Enable sticky behavior. Default: false */
3
+ enabled?: boolean;
4
+ /** Positions that support sticky (e.g., ["box-2", "box-3"]). Default: [] */
5
+ positions?: string[];
6
+ /** Minimum viewport height for sticky. Default: 768 */
7
+ minViewportHeight?: number;
8
+ /** Top offset in pixels. Default: 80 */
9
+ topOffset?: number;
10
+ /** CSS selector for header (for dynamic offset). Default: null */
11
+ headerSelector?: string | null;
12
+ /** Enable smooth transitions. Default: true */
13
+ smoothTransition?: boolean;
14
+ /** Transition duration in ms. Default: 150 */
15
+ transitionDuration?: number;
16
+ }
17
+ export interface StickyMetrics {
18
+ adId: string;
19
+ position: string;
20
+ stickyTime: number;
21
+ totalTime: number;
22
+ isCurrentlySticky: boolean;
23
+ }
@@ -0,0 +1,2 @@
1
+ export { ViewabilityService } from "./viewability.service";
2
+ export type { ViewabilityConfig, ViewabilityEvent, ViewabilityMetrics, } from "./viewability.types";
@@ -0,0 +1,38 @@
1
+ import type { ViewabilityConfig, ViewabilityMetrics } from "./viewability.types";
2
+ export declare class ViewabilityService {
3
+ private static config;
4
+ private static trackedAds;
5
+ /**
6
+ * Configure the viewability service
7
+ */
8
+ static configure(config: ViewabilityConfig): void;
9
+ /**
10
+ * Start tracking an ad element for viewability
11
+ */
12
+ static track(element: HTMLElement, adId: string, position: string): void;
13
+ /**
14
+ * Stop tracking an ad element
15
+ */
16
+ static untrack(adId: string): void;
17
+ /**
18
+ * Get metrics for a specific ad
19
+ */
20
+ static getMetrics(adId: string): ViewabilityMetrics | null;
21
+ /**
22
+ * Get all tracked metrics
23
+ */
24
+ static getAllMetrics(): ViewabilityMetrics[];
25
+ /**
26
+ * Show metrics summary in console
27
+ */
28
+ static showMetrics(): void;
29
+ /**
30
+ * Clear all tracking
31
+ */
32
+ static reset(): void;
33
+ private static handleIntersection;
34
+ private static startViewabilityTimer;
35
+ private static stopViewabilityTimer;
36
+ private static updateMetrics;
37
+ private static dispatchEvent;
38
+ }
@@ -0,0 +1,22 @@
1
+ export interface ViewabilityMetrics {
2
+ adId: string;
3
+ position: string;
4
+ isViewable: boolean;
5
+ viewableTime: number;
6
+ totalTime: number;
7
+ viewabilityRate: number;
8
+ }
9
+ export interface ViewabilityEvent {
10
+ type: "viewable" | "impression" | "hidden";
11
+ adId: string;
12
+ metrics: ViewabilityMetrics;
13
+ timestamp: number;
14
+ }
15
+ export interface ViewabilityConfig {
16
+ /** Minimum visibility ratio (0-1). Default: 0.5 (IAB standard) */
17
+ threshold?: number;
18
+ /** Time in ms to be considered viewable. Default: 2000 (IAB standard) */
19
+ duration?: number;
20
+ /** Enable console metrics output */
21
+ debug?: boolean;
22
+ }