waitless-api 0.1.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.
@@ -0,0 +1,62 @@
1
+ export interface AdConfig {
2
+ adTagUrl: string;
3
+ maxDuration?: number;
4
+ onAdStarted?: () => void;
5
+ onAdComplete?: () => void;
6
+ onAdError?: (error: any) => void;
7
+ onAdSkipped?: () => void;
8
+ }
9
+ declare global {
10
+ interface Window {
11
+ google?: {
12
+ ima: {
13
+ AdDisplayContainer: new (container: HTMLElement, videoElement: HTMLVideoElement) => any;
14
+ AdsLoader: new (adDisplayContainer: any) => any;
15
+ AdsManagerLoadedEvent: {
16
+ Type: {
17
+ ADS_MANAGER_LOADED: string;
18
+ };
19
+ };
20
+ AdErrorEvent: {
21
+ Type: {
22
+ AD_ERROR: string;
23
+ };
24
+ };
25
+ AdsRequest: new () => any;
26
+ AdsRenderingSettings: new () => any;
27
+ AdEvent: {
28
+ Type: {
29
+ CONTENT_PAUSE_REQUESTED: string;
30
+ CONTENT_RESUME_REQUESTED: string;
31
+ ALL_ADS_COMPLETED: string;
32
+ SKIPPED: string;
33
+ };
34
+ };
35
+ ViewMode: {
36
+ NORMAL: number;
37
+ };
38
+ };
39
+ };
40
+ }
41
+ }
42
+ export declare class AdPlayer {
43
+ private container;
44
+ private adDisplayContainer;
45
+ private adsLoader;
46
+ private adsManager;
47
+ private videoElement;
48
+ private adContainer;
49
+ private loadingOverlay;
50
+ private adBadge;
51
+ constructor(container: HTMLElement);
52
+ private setupElements;
53
+ private showLoadingOverlay;
54
+ private removeLoadingOverlay;
55
+ private showErrorOverlay;
56
+ playAd(config: AdConfig): Promise<void>;
57
+ private loadIMAScript;
58
+ private initializeAd;
59
+ private onAdsManagerLoaded;
60
+ private cleanup;
61
+ destroy(): void;
62
+ }
package/dist/core.d.ts ADDED
@@ -0,0 +1,132 @@
1
+ export type GameType = 'tetris' | 'snake' | 'breakout';
2
+ export type ThemeType = 'default' | 'cyberpunk' | 'minimal' | 'corporate';
3
+ /** Ad config shape from dashboard/backend (used by showAd and overrides) */
4
+ export interface WaitlessConfig {
5
+ strategy?: {
6
+ preset?: string;
7
+ behavior?: string;
8
+ };
9
+ frequency?: {
10
+ minInterval?: number;
11
+ maxAdsPerSession?: number;
12
+ maxAdsPerHour?: number;
13
+ };
14
+ duration?: {
15
+ shortThreshold?: number;
16
+ longThreshold?: number;
17
+ adMaxDuration?: number;
18
+ enableGames?: boolean;
19
+ };
20
+ batch?: {
21
+ enabled?: boolean;
22
+ showAdOnce?: boolean;
23
+ };
24
+ fallback?: {
25
+ type?: string;
26
+ showMessage?: boolean;
27
+ };
28
+ analytics?: {
29
+ trackEvents?: boolean;
30
+ enableABTesting?: boolean;
31
+ };
32
+ }
33
+ export interface GameOptions {
34
+ game?: GameType;
35
+ theme?: ThemeType;
36
+ message?: string;
37
+ container?: HTMLElement | string;
38
+ width?: number;
39
+ height?: number;
40
+ onStart?: () => void;
41
+ onScore?: (score: number) => void;
42
+ onEnd?: () => void;
43
+ showAds?: boolean;
44
+ adTagUrl?: string;
45
+ adDuration?: number;
46
+ adPlacement?: 'pre-game' | 'post-game' | 'both';
47
+ }
48
+ export declare class WaitlessAPI {
49
+ private apiKey;
50
+ private baseUrl;
51
+ private apiBaseUrl;
52
+ private defaultAdTagUrl;
53
+ private sessionId;
54
+ private container;
55
+ private gameInstance;
56
+ private isPlaying;
57
+ private lastBackendConfig;
58
+ private config;
59
+ private configLoaded;
60
+ private configPromise;
61
+ private batchIdsSeen;
62
+ private lastAdTime;
63
+ private adsThisSession;
64
+ private adsThisHour;
65
+ private lastHourStart;
66
+ /**
67
+ * Initialize the WaitlessAPI SDK
68
+ * @param apiKey Your WaitlessAPI key
69
+ * @param baseUrlOrOptions Base URL string or options object with apiBaseUrl (defaults to production)
70
+ */
71
+ constructor(apiKey: string, baseUrlOrOptions?: string | {
72
+ apiBaseUrl?: string;
73
+ });
74
+ private getDefaultConfig;
75
+ private getCachedConfig;
76
+ private cacheConfig;
77
+ private loadConfig;
78
+ /** Wait for config to be loaded (e.g. before using showAd). */
79
+ private ensureConfigLoaded;
80
+ /** Clear cache and reload config from API. */
81
+ refreshConfig(): Promise<void>;
82
+ /** Return current config (for debugging). */
83
+ getConfig(): WaitlessConfig | null;
84
+ /**
85
+ * Run processing with a minimal fallback UI (spinner/message). No ad or game.
86
+ */
87
+ private showProcessing;
88
+ private shouldShowAd;
89
+ private recordAdShown;
90
+ /**
91
+ * Config-driven entry point: show ad and/or game based on dashboard config, then run processing.
92
+ */
93
+ showAd<T>(processingFn: () => Promise<T>, options?: {
94
+ estimatedDuration?: number;
95
+ batchId?: string;
96
+ message?: string;
97
+ overrideConfig?: Partial<WaitlessConfig>;
98
+ }): Promise<T>;
99
+ /**
100
+ * Show a game while executing a long-running function
101
+ * @param processingFn The function to execute while showing the game
102
+ * @param options Game configuration options
103
+ * @returns Promise with the result of the processing function
104
+ */
105
+ showGame<T>(processingFn: () => Promise<T>, options?: GameOptions): Promise<T>;
106
+ /**
107
+ * Create a new game session with the API
108
+ * @param options Game options
109
+ * @returns Session id and config (null for demo/offline)
110
+ */
111
+ private createSession;
112
+ /**
113
+ * Initialize the game UI container
114
+ * @param options Game options
115
+ * @returns container and overlay (overlay is non-null when we created the full-screen div)
116
+ */
117
+ private initializeGameUI;
118
+ /**
119
+ * Start the game
120
+ * @param options Game options
121
+ * @returns The game instance
122
+ */
123
+ private startGame;
124
+ private playAdInContainer;
125
+ private trackAdEvent;
126
+ private cleanup;
127
+ /**
128
+ * End the game and send session complete (overlay removal is done in cleanup)
129
+ */
130
+ private endGame;
131
+ private completeSession;
132
+ }
@@ -0,0 +1,54 @@
1
+ import { ThemeType } from '../core';
2
+ export interface GameConfig {
3
+ container: HTMLElement;
4
+ theme?: ThemeType;
5
+ onScore?: (score: number) => void;
6
+ /** Backend/sync: dimensions and speed */
7
+ width?: number;
8
+ height?: number;
9
+ speed?: number;
10
+ /** Game-specific (Tetris: blockSize, scoring; Snake: gridSize, foodValue; Breakout: paddleWidth, brickRows, ballSpeed) */
11
+ [key: string]: any;
12
+ }
13
+ /**
14
+ * Base game class with common functionality
15
+ */
16
+ export declare abstract class BaseGame {
17
+ protected container: HTMLElement;
18
+ protected theme: ThemeType;
19
+ protected isRunning: boolean;
20
+ protected score: number;
21
+ protected onScoreCallback?: (score: number) => void;
22
+ constructor(config: GameConfig);
23
+ /**
24
+ * Start the game
25
+ */
26
+ abstract start(): void;
27
+ /**
28
+ * Pause the game
29
+ */
30
+ abstract pause(): void;
31
+ /**
32
+ * Resume the game
33
+ */
34
+ abstract resume(): void;
35
+ /**
36
+ * Destroy the game and clean up
37
+ */
38
+ abstract destroy(): void;
39
+ /**
40
+ * Update the score and trigger callback
41
+ * @param points Points to add to the score
42
+ */
43
+ protected updateScore(points: number): void;
44
+ /**
45
+ * Get the current score
46
+ * @returns Current score
47
+ */
48
+ getScore(): number;
49
+ /**
50
+ * Check if the game is currently running
51
+ * @returns Whether the game is running
52
+ */
53
+ isActive(): boolean;
54
+ }
@@ -0,0 +1,45 @@
1
+ import { BaseGame, GameConfig } from './base';
2
+ /**
3
+ * Breakout game implementation
4
+ */
5
+ export default class BreakoutGame extends BaseGame {
6
+ private canvas;
7
+ private ctx;
8
+ private paddle;
9
+ private ball;
10
+ private bricks;
11
+ private animationFrame;
12
+ private lastTime;
13
+ private ballLaunched;
14
+ private lives;
15
+ private level;
16
+ private highScore;
17
+ private paused;
18
+ private readonly width;
19
+ private readonly height;
20
+ private readonly paddleWidth;
21
+ private readonly paddleHeight;
22
+ private readonly ballRadius;
23
+ private readonly brickRows;
24
+ private readonly brickColumns;
25
+ private baseBallSpeed;
26
+ private brickPadding;
27
+ private brickOffsetTop;
28
+ constructor(config: GameConfig);
29
+ private getColors;
30
+ start(): void;
31
+ pause(): void;
32
+ resume(): void;
33
+ destroy(): void;
34
+ private update;
35
+ private initBricks;
36
+ private resetGame;
37
+ private launchBall;
38
+ private updateGameState;
39
+ private draw;
40
+ private handleMouseMove;
41
+ private handleTouchMove;
42
+ private handleClick;
43
+ private handleKeyDown;
44
+ private setupControls;
45
+ }
@@ -0,0 +1,11 @@
1
+ import { GameType } from '../core';
2
+ import { GameConfig } from './base';
3
+ export { GameConfig } from './base';
4
+ export { BaseGame } from './base';
5
+ /**
6
+ * Load a game instance
7
+ * @param gameType Type of game to load
8
+ * @param config Game configuration
9
+ * @returns Game instance
10
+ */
11
+ export declare function loadGame(gameType: GameType, config: GameConfig): any;
@@ -0,0 +1,40 @@
1
+ import { BaseGame, GameConfig } from './base';
2
+ /**
3
+ * Snake game implementation
4
+ */
5
+ export default class SnakeGame extends BaseGame {
6
+ private canvas;
7
+ private ctx;
8
+ private snake;
9
+ private food;
10
+ private direction;
11
+ private nextDirection;
12
+ private animationFrame;
13
+ private lastTime;
14
+ private moveInterval;
15
+ private moveCounter;
16
+ private highScore;
17
+ private gridSize;
18
+ private cellSize;
19
+ private gridWidth;
20
+ private gridHeight;
21
+ private foodValue;
22
+ private touchStartX;
23
+ private touchStartY;
24
+ constructor(config: GameConfig);
25
+ private getColors;
26
+ start(): void;
27
+ pause(): void;
28
+ resume(): void;
29
+ destroy(): void;
30
+ private update;
31
+ private draw;
32
+ private resetGame;
33
+ private spawnFood;
34
+ private moveSnake;
35
+ private gameOver;
36
+ private handleKeyDown;
37
+ private handleTouchStart;
38
+ private handleTouchEnd;
39
+ private setupControls;
40
+ }
@@ -0,0 +1,94 @@
1
+ import { BaseGame, GameConfig } from './base';
2
+ /**
3
+ * Tetris game implementation
4
+ */
5
+ export default class TetrisGame extends BaseGame {
6
+ private canvas;
7
+ private ctx;
8
+ private grid;
9
+ private currentPiece;
10
+ private nextPiece;
11
+ private animationFrame;
12
+ private lastTime;
13
+ private dropInterval;
14
+ private dropCounter;
15
+ private cols;
16
+ private rows;
17
+ private blockSize;
18
+ private scoring;
19
+ private readonly shapes;
20
+ private readonly colors;
21
+ constructor(config: GameConfig);
22
+ /**
23
+ * Start the game
24
+ */
25
+ start(): void;
26
+ /**
27
+ * Pause the game
28
+ */
29
+ pause(): void;
30
+ /**
31
+ * Resume the game
32
+ */
33
+ resume(): void;
34
+ /**
35
+ * Destroy the game and clean up
36
+ */
37
+ destroy(): void;
38
+ /**
39
+ * Main game update loop
40
+ */
41
+ private update;
42
+ /**
43
+ * Draw the game state
44
+ */
45
+ private draw;
46
+ /**
47
+ * Draw the game grid
48
+ */
49
+ private drawGrid;
50
+ /**
51
+ * Draw a tetromino piece
52
+ */
53
+ private drawPiece;
54
+ /**
55
+ * Reset the game grid
56
+ */
57
+ private resetGrid;
58
+ /**
59
+ * Create a new tetromino piece
60
+ */
61
+ private createPiece;
62
+ /**
63
+ * Move the current piece down
64
+ */
65
+ private dropPiece;
66
+ /**
67
+ * Check if the current piece collides with the grid or boundaries
68
+ */
69
+ private checkCollision;
70
+ /**
71
+ * Merge the current piece with the grid
72
+ */
73
+ private mergePiece;
74
+ /**
75
+ * Check for completed lines and remove them
76
+ */
77
+ private checkLines;
78
+ /**
79
+ * Move the current piece left or right
80
+ */
81
+ private movePiece;
82
+ /**
83
+ * Rotate the current piece
84
+ */
85
+ private rotatePiece;
86
+ /**
87
+ * Handle keyboard input
88
+ */
89
+ private handleKeyDown;
90
+ /**
91
+ * Set up control event listeners
92
+ */
93
+ private setupControls;
94
+ }
@@ -0,0 +1,4 @@
1
+ import { WaitlessAPI, GameOptions, GameType, ThemeType, WaitlessConfig } from './core';
2
+ export { WaitlessAPI, GameOptions, GameType, ThemeType, WaitlessConfig };
3
+ export { AdPlayer, AdConfig } from './ads/AdPlayer';
4
+ export default WaitlessAPI;