@smoud/playable-sdk 1.0.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/README.md ADDED
@@ -0,0 +1,397 @@
1
+ # @smoud/playable-sdk
2
+
3
+ [![npm version](https://badgen.net/npm/v/@smoud/playable-sdk)](https://npm.im/@smoud/playable-sdk)
4
+ [![npm downloads](https://badgen.net/npm/dm/@smoud/playable-sdk)](https://npm.im/@smoud/playable-sdk)
5
+
6
+ It's powerful, unified SDK that seamlessly integrates multiple ad network SDKs, including MRAID, Google, Facebook, Vungle, and many more. Designed for effortless playable ad development, it provides a standardized interface, ensuring compatibility, optimization, and easy deployment across various platforms. With @smoud/playable-sdk, you can streamline your workflow, maximize reach, and focus on crafting engaging interactive ads without worrying about SDK fragmentation. 🚀
7
+
8
+ ## Features
9
+
10
+ - 🌐 **Universal Compatibility**: Works with all major ad networks
11
+ - 🔄 **Standardized Interface**: Single API for all supported networks
12
+ - 📱 **Responsive Design**: Automatic handling of orientation and resize events
13
+ - 🎮 **Game State Management**: Built-in pause/resume and lifecycle management
14
+ - 🔊 **Audio Control**: Volume management across different networks
15
+ - 📊 **Interaction Tracking**: Built-in user interaction monitoring
16
+ - ⚡ **Lightweight**: No external dependencies
17
+
18
+ ## Supported Ad Networks
19
+
20
+ ### Ad Network supports
21
+
22
+ - IronSource (MRAID/DAPI)
23
+ - AppLovin
24
+ - Unity Ads
25
+ - Google Ads
26
+ - Meta (Facebook)
27
+ - Moloco
28
+ - Mintegral
29
+ - Vungle
30
+ - TapJoy
31
+ - Snapchat
32
+ - TikTok
33
+ - Appreciate
34
+ - Pangle
35
+ - Liftoff
36
+ - Chartboost
37
+ - AdColony
38
+ - MyTarget
39
+
40
+ ### Protocol Support
41
+
42
+ The SDK automatically detects and adapts to the appropriate ad network protocol:
43
+
44
+ - MRAID Protocol (v2/v3)
45
+ - DAPI Protocol (Display Ad Protocol Interface)
46
+ - Network-specific protocols (Facebook, Google, etc.)
47
+
48
+ ## Installation
49
+
50
+ ```bash
51
+ npm install @smoud/playable-sdk
52
+ ```
53
+
54
+ ## Build
55
+
56
+ ### Introduction: @smoud/playable-scripts
57
+
58
+ `@smoud/playable-sdk` works best with the **@smoud/playable-scripts** package, which helps you prepare **playable ad builds** that are ready for multiple ad networks. Using `playable-scripts` provides key benefits:
59
+
60
+ - 🚀 **One-Command Build Process** – Easily generate builds for different ad networks.
61
+ - ⚡ **Automatic Optimizations** – Includes minification, tree-shaking, and dead code elimination.
62
+ - 🎯 **Pre-configured for Major Ad Networks** – Works out of the box with **Google Ads, Meta (Facebook), AppLovin, Unity, IronSource, Vungle, Mintegral, and more**.
63
+ - 🛠️ **Customizable** – Extend the default build pipeline as needed.
64
+
65
+ ### 🔧 Quick Start
66
+
67
+ #### 1️⃣ Install **@smoud/playable-scripts**
68
+
69
+ Install the package in your project:
70
+
71
+ ```sh
72
+ npm i --save-dev @smoud/playable-scripts
73
+ ```
74
+
75
+ #### 2️⃣ Update `package.json`
76
+
77
+ Modify your `package.json` file to include the following scripts:
78
+
79
+ ```json
80
+ "scripts": {
81
+ "dev": "playable-scripts dev",
82
+ "build": "playable-scripts build"
83
+ }
84
+ ```
85
+
86
+ #### 3️⃣ Run the development server
87
+
88
+ Start a local development server with live reloading:
89
+
90
+ ```sh
91
+ npm run dev
92
+ ```
93
+
94
+ #### 4️⃣ Build for a specific ad network
95
+
96
+ To generate a playable ad ready for an ad network, use the build command:
97
+
98
+ ```sh
99
+ npm run build <ad-network>
100
+ ```
101
+
102
+ ##### Examples:
103
+ To build for **Applovin**, run:
104
+
105
+ ```sh
106
+ npm run build applovin
107
+ ```
108
+
109
+ To build for **IronSource DAPI**, run:
110
+
111
+ ```sh
112
+ npm run build ironsource -- --dapi
113
+ ```
114
+
115
+ Supported **Ad Networks**:
116
+
117
+ - `applovin`
118
+ - `unity`
119
+ - `google`
120
+ - `ironsource`
121
+ - `facebook`
122
+ - `moloco`
123
+ - `mintegral`
124
+ - `vungle`
125
+ - `tapjoy`
126
+ - `snapchat`
127
+ - `tiktok`
128
+ - `appreciate`
129
+ - `chartboost`
130
+ - `pangle`
131
+ - `mytarget`
132
+ - `liftoff`
133
+
134
+ ## Custom Build Pipeline
135
+
136
+ Before setting up a custom pipeline, consider using **@smoud/playable-scripts**. It provides an API to extend the standard build function and simplifies the process.
137
+
138
+ If you still prefer a fully custom build, you need to manage the following aspects yourself:
139
+
140
+ ### 1️⃣ Define Required Variables
141
+ Your build script should replace or define these variables within the `window` object before the rest of your code executes:
142
+
143
+ ```ts
144
+ AD_NETWORK = 'applovin'; // Replace with your target network
145
+ AD_PROTOCOL = 'mraid'; // Options: 'mraid', 'dapi', 'none'
146
+ GOOGLE_PLAY_URL = 'https://play.google.com/store/apps/details?id=com.example';
147
+ APP_STORE_URL = 'https://apps.apple.com/app/id123456789';
148
+ BUILD_HASH = 'random-build-hash';
149
+ ```
150
+
151
+ ### 2️ Applying Ad-Specific Adjustments
152
+ Certain networks use different ad protocols. Ensure that your build includes or removes code based on the network.
153
+
154
+ Check [Ad Network Resources & Requirements](#Ad-Network-Resources-&-Requirements) for more details.
155
+
156
+ ### 3️⃣ Minification & Optimization
157
+ To ensure the best performance, your build should include a **JavaScript minimizer** to remove unnecessary code.
158
+
159
+ #### Recommended Tools:
160
+ - [Terser](https://github.com/terser/terser) – Best for JS minification.
161
+ - [UglifyJS](https://github.com/mishoo/UglifyJS) – Alternative for JS compression.
162
+
163
+ ## Quick Start
164
+
165
+ ```javascript
166
+ import { sdk } from '@smoud/playable-sdk';
167
+
168
+ // Initialize the SDK as early as possible
169
+ sdk.init((width, height) => {
170
+ // Initialize your game/app with container dimensions
171
+ new Game(width, height);
172
+ });
173
+ ```
174
+
175
+ ```javascript
176
+ // Listen for events
177
+ sdk.on('resize', (width, height) => {
178
+ game.resize(width, height);
179
+ });
180
+
181
+ sdk.on('pause', game.pause, game);
182
+ sdk.on('resume', game.resume, game);
183
+ sdk.on('volume', game.volume, game);
184
+ sdk.on('finish', game.finish, game);
185
+
186
+ sdk.on('interaction', (count) => {
187
+ console.log(`User interaction count: ${count}`);
188
+ });
189
+ ```
190
+
191
+ ```javascript
192
+ // Start the playable when resources are loaded
193
+ sdk.start();
194
+ ```
195
+
196
+ ```javascript
197
+ // Mark playable as complete
198
+ sdk.finish();
199
+
200
+ // Handle install/download action
201
+ installButton.onclick = () => sdk.install();
202
+ ```
203
+
204
+ ## SDK API Reference
205
+
206
+ ### Lifecycle Management & typical usage
207
+
208
+ The SDK provides a comprehensive set of functions to manage the playable ad lifecycle. Functions should be called in the following order:
209
+
210
+ 1. **Initialization & Setup**
211
+
212
+ ```javascript
213
+ // Initialize SDK (required first call)
214
+ sdk.init((width, height) => {
215
+ // Setup your app with container dimensions
216
+ });
217
+
218
+ // Start playable after resources are loaded
219
+ sdk.start();
220
+ ```
221
+
222
+ 2. **Listen for needed events**
223
+
224
+ #### **RECOMMENDED** events For best user experience
225
+
226
+ ```javascript
227
+ sdk.on('resize', (width, height) => {
228
+ // Update game layout on container resize
229
+ game.updateLayout(width, height);
230
+ ui.repositionElements();
231
+ });
232
+
233
+ sdk.on('pause', () => {
234
+ // Pause gameplay when ad container loses focus
235
+ game.pauseGameplay();
236
+ ui.showPauseOverlay();
237
+ });
238
+
239
+ sdk.on('resume', () => {
240
+ // Resume gameplay when focus returns
241
+ game.resumeGameplay();
242
+ ui.hidePauseOverlay();
243
+ });
244
+
245
+ sdk.on('volume', (level) => {
246
+ // Adjust game audio when container volume changes
247
+ audio.setVolume(level);
248
+ ui.updateVolumeIndicator(level);
249
+
250
+ // if (level === 0) audio.muteGlobal();
251
+ // else audio.unMuteGlobal();
252
+ });
253
+
254
+ sdk.on('finish', () => {
255
+ // Show end screen when playable is marked complete
256
+ game.stopGameplay();
257
+ ui.showEndScreen();
258
+ });
259
+ ```
260
+ #### Optional events
261
+ ```javascript
262
+ sdk.on('init', () => {
263
+ // Show loading screen while SDK initializes
264
+ loadingScreen.show();
265
+ });
266
+
267
+ sdk.on('ready', () => {
268
+ // You should use either init callback function or this event to initialize your game
269
+ // They are performing just in the same condition, so avoid creating game instance duplication
270
+ new Game(sdk.maxWidth, sdk.maxHeight);
271
+ });
272
+
273
+ sdk.on('start', () => {
274
+ // Begin gameplay/animation when playable officially starts
275
+ game.startGameplay();
276
+ loadingScreen.hide();
277
+ });
278
+
279
+ sdk.on('interaction', (count) => {
280
+ // Track user engagement
281
+ analytics.logInteraction(count);
282
+ if (count >= 3) {
283
+ // Show CTA after sufficient engagement
284
+ game.showCallToAction();
285
+ }
286
+ });
287
+
288
+ sdk.on('retry', () => {
289
+ // Reset game state for replay
290
+ game.reset();
291
+ ui.hideEndScreen();
292
+ game.startGameplay();
293
+ });
294
+
295
+ sdk.on('install', () => {
296
+ // Track conversion when install/store action triggered
297
+ analytics.logConversion();
298
+ });
299
+ ```
300
+
301
+ 3. **Mark all resources are preloaded and gameplay is started**
302
+
303
+ ```javascript
304
+ // Start playable after resources are loaded
305
+ sdk.start();
306
+ ```
307
+
308
+ 4. **Completion & Installation**
309
+
310
+ ```javascript
311
+ // Mark playable as complete
312
+ sdk.finish();
313
+
314
+ // Trigger install/store redirect
315
+ sdk.install();
316
+ ```
317
+
318
+ ### Event System
319
+
320
+ Events are emitted throughout the playable lifecycle and can be handled using:
321
+
322
+ ```javascript
323
+ // Regular event listener
324
+ sdk.on('eventName', callback, [context]);
325
+
326
+ // One-time event listener
327
+ sdk.once('eventName', callback, [context]);
328
+
329
+ // Remove listener(s)
330
+ sdk.off('eventName', [callback], [context]);
331
+ ```
332
+
333
+ #### Available Events
334
+
335
+ | Event | Parameters | Description | Typical Usage |
336
+ | ------------- | --------------- | ------------------------------------------ | ------------------------ |
337
+ | `init` | - | SDK initialization started | Setup loading screen |
338
+ | `boot` | - | Ad container is ready `pre` init callback | Initialize core systems |
339
+ | `ready` | - | Ad container is ready `post` init callback | Start resource loading |
340
+ | `start` | - | Playable experience started | Begin gameplay/animation |
341
+ | `interaction` | `count` | User interaction occurred | Track engagement |
342
+ | `resize` | `width, height` | Container size changed | Update layout |
343
+ | `pause` | - | Playable entered pause state | Pause gameplay |
344
+ | `resume` | - | Playable resumed from pause | Resume gameplay |
345
+ | `volume` | `level` | Volume level changed (0-1) | Adjust audio |
346
+ | `retry` | - | Retry/restart triggered | Reset game state |
347
+ | `finish` | - | Playable marked as complete | Show end screen |
348
+ | `install` | - | Install action triggered | Track conversion |
349
+
350
+ ### Properties
351
+
352
+ | Property | Type | Description |
353
+ | ------------------ | ------- | ------------------------------------------------------ |
354
+ | `sdk.version` | string | Current SDK version |
355
+ | `sdk.maxWidth` | number | Container width in pixels |
356
+ | `sdk.maxHeight` | number | Container height in pixels |
357
+ | `sdk.isLandscape` | boolean | Current device orientation state |
358
+ | `sdk.isReady` | boolean | Ad container ready state |
359
+ | `sdk.isStarted` | boolean | All resources are loaded and playable started state |
360
+ | `sdk.isPaused` | boolean | Current pause state |
361
+ | `sdk.isFinished` | boolean | Completion state |
362
+ | `sdk.volume` | number | Default volume level (0-1), when muting/unmuting audio |
363
+ | `sdk.interactions` | number | User interaction count |
364
+
365
+ ## References
366
+
367
+ ### Ad Network Resources & Requirements
368
+
369
+ #### MRAID Networks
370
+
371
+ - [MRAID 3.0](https://www.iab.com/wp-content/uploads/2017/07/MRAID_3.0_FINAL.pdf)
372
+ - [IronSource - MRAID requirements](https://developers.is.com/ironsource-mobile/general/mraid-requirements/#step-1)
373
+ - [IronSource - Interactive ad creative requirements](https://developers.is.com/ironsource-mobile/general/interactive-requirements/#step-1)
374
+ - [Unity Ads Documentation](https://docs.unity.com/acquire/en-us/manual/playable-ads-specifications)
375
+ - [Chartboost Integration](https://docs.chartboost.com/en/advertising/creatives/creative-assets/)
376
+
377
+ #### Proprietary Networks
378
+
379
+ - [Google HTML5 / Playable Ads](https://support.google.com/google-ads/answer/9981650?hl=en)
380
+ - [Meta (Facebook) Playable Ads](https://www.facebook.com/business/help/412951382532338)
381
+ - [Mintegral Integration](https://www.playturbo.com/review/doc)
382
+
383
+ ### Testing Tools
384
+
385
+ #### Network Testing Tools
386
+
387
+ - Applovin Playable [Web](https://p.applov.in/playablePreview?create=1&;qr=1) / [iOS](https://install.appcenter.ms/orgs/iosdeveloper-dbmy/apps/ios-playable-preview/distribution_groups/all-users-of-ios-playable-preview) / [Android](https://install.appcenter.ms/orgs/iosdeveloper-dbmy/apps/android-playable-preview/distribution_groups/all-users-of-android-playable-preview)
388
+ - Unity Ad Testing [iOS](https://apps.apple.com/us/app/ad-testing/id1463016906) / [Android](https://play.google.com/store/apps/details?id=com.unity3d.auicreativetestapp)
389
+ - [Vungle Creative QA](https://vungle.com/creative-verifier/)
390
+ - [Facebook Playable Preview Tool](https://developers.facebook.com/tools/playable-preview/)
391
+ - [Google HTML5 Validator](https://h5validator.appspot.com/adwords/asset)
392
+ - [IronSource Integration Validation](https://developers.is.com/ironsource-mobile/general/test-suite/)
393
+ - [Mintegral Testing Tool](https://www.playturbo.com/review/doc)
394
+
395
+ ## Issues
396
+
397
+ Report issues at [GitHub Issues](https://github.com/smoudjs/playable-sdk/issues)
package/defines.d.ts ADDED
@@ -0,0 +1,94 @@
1
+ declare const mraid: {
2
+ isReady: () => boolean;
3
+ isViewable: () => boolean;
4
+ getState: () => string;
5
+ addEventListener: (
6
+ event: 'viewableChange' | 'sizeChange' | 'ready' | 'audioVolumeChange' | 'stateChange' | 'error',
7
+ callback: (...args: any[]) => void
8
+ ) => void;
9
+ removeEventListener: (
10
+ event: 'viewableChange' | 'sizeChange' | 'ready' | 'audioVolumeChange' | 'stateChange' | 'error',
11
+ callback: (...args: any[]) => void
12
+ ) => void;
13
+ getMaxSize: () => { width: number; height: number };
14
+ openStoreUrl: () => void;
15
+ open: (url: string) => void;
16
+ preloadStore?: () => void;
17
+ };
18
+
19
+ declare const dapi: {
20
+ addEventListener: (
21
+ event: 'viewableChange' | 'adResized' | 'ready' | 'audioVolumeChange' | 'error',
22
+ callback: (...args: any[]) => void
23
+ ) => void;
24
+ removeEventListener: (
25
+ event: 'viewableChange' | 'adResized' | 'ready' | 'audioVolumeChange' | 'error',
26
+ callback: (...args: any[]) => void
27
+ ) => void;
28
+ getScreenSize: () => { width: number; height: number };
29
+ openStoreUrl: () => void;
30
+ getAudioVolume: () => number;
31
+ isViewable: () => boolean;
32
+ isReady: () => boolean;
33
+ };
34
+
35
+ declare const NUC: {
36
+ trigger: {
37
+ convert: (destinationUrl: string) => void;
38
+ tryAgain: Function;
39
+ };
40
+ };
41
+
42
+ declare const FbPlayableAd: { onCTAClick: () => void };
43
+ declare const ExitApi: { exit: () => void };
44
+
45
+ declare const AD_NETWORK:
46
+ | 'applovin'
47
+ | 'unity'
48
+ | 'google'
49
+ | 'ironsource'
50
+ | 'facebook'
51
+ | 'moloco'
52
+ | 'mintegral'
53
+ | 'vungle'
54
+ | 'adcolony'
55
+ | 'tapjoy'
56
+ | 'snapchat'
57
+ | 'tiktok'
58
+ | 'appreciate'
59
+ | 'chartboost'
60
+ | 'pangle'
61
+ | 'mytarget'
62
+ | 'liftoff';
63
+ declare const AD_PROTOCOL: 'mraid' | 'dapi' | 'nucleo' | 'none';
64
+ declare const GOOGLE_PLAY_URL: string;
65
+ declare const APP_STORE_URL: string;
66
+ declare const BUILD_HASH: string;
67
+
68
+ // Mintegral functions
69
+ declare const gameStart: Function;
70
+ declare const gameClose: Function;
71
+
72
+ interface Window {
73
+ PlayableSDK: any;
74
+
75
+ // Mintegral functions
76
+ gameReady: Function;
77
+ gameEnd: Function;
78
+ gameRetry: Function;
79
+ install: Function;
80
+ mintGameStart: Function,
81
+ mintGameClose: Function
82
+
83
+ // Tapjoy functions
84
+ TJ_API: {
85
+ objectiveComplete: Function;
86
+ playableFinished: Function;
87
+ gameplayFinished: Function;
88
+ setPlayableBuild: Function;
89
+ setPlayableAPI: Function
90
+ click: Function;
91
+ };
92
+
93
+ openAppStore: Function;
94
+ }