@playcraft/adsdk 1.0.6 → 1.0.8

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/defines.d.ts CHANGED
@@ -88,6 +88,12 @@ interface Window {
88
88
  landUrl: string;
89
89
  };
90
90
 
91
+ // AppLovin Playable Analytics
92
+ // 文档: https://support.axon.ai/en/growth/promoting-your-apps/creatives/playable-analytics-integration
93
+ ALPlayableAnalytics?: {
94
+ trackEvent: (event: string) => void;
95
+ };
96
+
91
97
  // BigoAds SDK
92
98
  // 文档: https://www.bigoads.com/help/detail?id=143&moduleId=7&currentLan=CN
93
99
  BGY_MRAID: {
package/dist/esm/index.js CHANGED
@@ -158,53 +158,174 @@ function ensureProtocol() {
158
158
  }
159
159
 
160
160
  // src/tracking.ts
161
+ function trackURL(url) {
162
+ if (url) {
163
+ const trackingPixel = new Image();
164
+ trackingPixel.src = url;
165
+ }
166
+ }
167
+ function trackBigabidEvent(event) {
168
+ console.log(" trackBigabidEvent", event);
169
+ if (window.BIGABID_BIDTIMEMACROS && window.BIGABID_BIDTIMEMACROS[event]) {
170
+ trackURL(window.BIGABID_BIDTIMEMACROS[event]);
171
+ }
172
+ }
173
+ function trackInMobiEvent(event) {
174
+ console.log(" trackInMobiEvent", event);
175
+ if (window.INMOBI_DSPMACROS && window.INMOBI_DSPMACROS[event]) {
176
+ trackURL(window.INMOBI_DSPMACROS[event]);
177
+ }
178
+ }
179
+ function trackApplovinEvent(event) {
180
+ console.log(" trackApplovinEvent", event);
181
+ if (typeof window.ALPlayableAnalytics !== "undefined") {
182
+ window.ALPlayableAnalytics.trackEvent(event);
183
+ }
184
+ }
185
+ var totalInteractions = 0;
186
+ var progressMilestones = [];
187
+ function setTotalInteractions(total) {
188
+ totalInteractions = total;
189
+ }
190
+ function trackChallengeSuccess() {
191
+ if (AD_NETWORK === "applovin") {
192
+ trackApplovinEvent("CHALLENGE_SOLVED");
193
+ }
194
+ if (AD_NETWORK === "bigabid") {
195
+ trackBigabidComplete();
196
+ }
197
+ if (AD_NETWORK === "inmobi") {
198
+ trackInMobiEvent("Gameplay_Complete");
199
+ }
200
+ }
201
+ function trackChallengeFailed() {
202
+ if (AD_NETWORK === "applovin") {
203
+ trackApplovinEvent("CHALLENGE_FAILED");
204
+ }
205
+ }
206
+ function initProgressMilestones() {
207
+ if (totalInteractions <= 0) return;
208
+ if (AD_NETWORK === "applovin") {
209
+ progressMilestones = [
210
+ { percent: 25, triggered: false, callback: () => trackApplovinEvent("CHALLENGE_PASS_25") },
211
+ { percent: 50, triggered: false, callback: () => trackApplovinEvent("CHALLENGE_PASS_50") },
212
+ { percent: 75, triggered: false, callback: () => trackApplovinEvent("CHALLENGE_PASS_75") },
213
+ { percent: 100, triggered: false, callback: () => trackChallengeSuccess() }
214
+ ];
215
+ } else if (AD_NETWORK === "bigabid") {
216
+ progressMilestones = [
217
+ { percent: 100, triggered: false, callback: () => trackChallengeSuccess() }
218
+ ];
219
+ }
220
+ }
221
+ function checkInteractionProgress(currentInteractions) {
222
+ if (totalInteractions <= 0 || progressMilestones.length === 0) return;
223
+ const currentPercent = currentInteractions / totalInteractions * 100;
224
+ for (const milestone of progressMilestones) {
225
+ if (!milestone.triggered && currentPercent >= milestone.percent) {
226
+ milestone.triggered = true;
227
+ milestone.callback();
228
+ }
229
+ }
230
+ }
231
+ var bigabidCompleteTriggered = false;
232
+ function trackBigabidComplete() {
233
+ if (!bigabidCompleteTriggered) {
234
+ trackBigabidEvent("complete");
235
+ bigabidCompleteTriggered = true;
236
+ }
237
+ }
238
+ var inmobiTimers = [];
239
+ function startInMobiDurationTracking() {
240
+ const durations = [5, 10, 15, 20, 25, 30];
241
+ for (const sec of durations) {
242
+ const timer = setTimeout(() => trackInMobiEvent(`Spent_${sec}_Seconds`), sec * 1e3);
243
+ inmobiTimers.push(timer);
244
+ }
245
+ }
246
+ function clearInMobiDurationTracking() {
247
+ for (const timer of inmobiTimers) {
248
+ clearTimeout(timer);
249
+ }
250
+ inmobiTimers = [];
251
+ }
161
252
  function initTrackingProtocols() {
162
- if (AD_NETWORK === "bigabid" || AD_NETWORK === "inmobi") {
163
- let trackURL2 = function(url) {
164
- if (url) {
165
- const trackingPixel = new Image();
166
- trackingPixel.src = url;
167
- }
168
- };
169
- var trackURL = trackURL2;
253
+ const supportedNetworks = ["bigabid", "inmobi", "applovin"];
254
+ if (!supportedNetworks.includes(AD_NETWORK)) {
255
+ return;
256
+ }
257
+ initProgressMilestones();
258
+ sdk.once("init", () => {
170
259
  if (AD_NETWORK === "bigabid") {
171
- let trackBigabidEvent2 = function(event) {
172
- if (window.BIGABID_BIDTIMEMACROS && window.BIGABID_BIDTIMEMACROS[event])
173
- trackURL2(window.BIGABID_BIDTIMEMACROS[event]);
174
- }, trackComplete2 = function() {
175
- if (!completeTriggered) trackBigabidEvent2("complete");
176
- completeTriggered = true;
177
- };
178
- var trackBigabidEvent = trackBigabidEvent2, trackComplete = trackComplete2;
179
- var completeTriggered = false;
180
- sdk.once("boot", () => trackBigabidEvent2("mraid_viewable"));
181
- sdk.once("start", () => trackBigabidEvent2("game_viewable"));
182
- sdk.once("interaction", () => trackBigabidEvent2("engagement"));
183
- sdk.once("finish", trackComplete2);
184
- sdk.on("interaction", (interactions) => {
185
- if (interactions > 3) trackComplete2();
186
- });
187
- sdk.once("install", () => trackBigabidEvent2("click"));
188
- } else if (AD_NETWORK === "inmobi") {
189
- let trackInMobiEvent2 = function(event) {
190
- if (window.INMOBI_DSPMACROS && window.INMOBI_DSPMACROS[event]) trackURL2(window.INMOBI_DSPMACROS[event]);
191
- };
192
- var trackInMobiEvent = trackInMobiEvent2;
193
- sdk.once("boot", () => trackInMobiEvent2("Ad_Load_Start"));
194
- sdk.once("start", () => trackInMobiEvent2("Ad_Viewable"));
195
- sdk.once("interaction", () => trackInMobiEvent2("First_Engagement"));
196
- sdk.once("finish", () => trackInMobiEvent2("Gameplay_Complete"));
197
- sdk.once("install", () => trackInMobiEvent2("DSP_Click"));
198
- sdk.once("start", () => {
199
- setTimeout(() => trackInMobiEvent2("Spent_5_Seconds"), 5e3);
200
- setTimeout(() => trackInMobiEvent2("Spent_10_Seconds"), 1e4);
201
- setTimeout(() => trackInMobiEvent2("Spent_15_Seconds"), 15e3);
202
- setTimeout(() => trackInMobiEvent2("Spent_20_Seconds"), 2e4);
203
- setTimeout(() => trackInMobiEvent2("Spent_25_Seconds"), 25e3);
204
- setTimeout(() => trackInMobiEvent2("Spent_30_Seconds"), 3e4);
205
- });
260
+ trackBigabidEvent("mraid_viewable");
206
261
  }
207
- }
262
+ if (AD_NETWORK === "inmobi") {
263
+ trackInMobiEvent("Ad_Load_Start");
264
+ }
265
+ if (AD_NETWORK === "applovin") {
266
+ trackApplovinEvent("LOADING");
267
+ }
268
+ });
269
+ sdk.once("start", () => {
270
+ if (AD_NETWORK === "bigabid") {
271
+ trackBigabidEvent("game_viewable");
272
+ }
273
+ if (AD_NETWORK === "inmobi") {
274
+ trackInMobiEvent("Ad_Viewable");
275
+ startInMobiDurationTracking();
276
+ }
277
+ if (AD_NETWORK === "applovin") {
278
+ trackApplovinEvent("LOADED");
279
+ }
280
+ });
281
+ sdk.once("interactive", () => {
282
+ if (AD_NETWORK === "applovin") {
283
+ trackApplovinEvent("DISPLAYED");
284
+ }
285
+ });
286
+ sdk.once("interaction", () => {
287
+ if (AD_NETWORK === "bigabid") {
288
+ trackBigabidEvent("engagement");
289
+ }
290
+ if (AD_NETWORK === "inmobi") {
291
+ trackInMobiEvent("First_Engagement");
292
+ }
293
+ if (AD_NETWORK === "applovin") {
294
+ trackApplovinEvent("CHALLENGE_STARTED");
295
+ }
296
+ });
297
+ sdk.on("success", (successCount) => {
298
+ checkInteractionProgress(successCount);
299
+ });
300
+ sdk.once("finish", () => {
301
+ if (AD_NETWORK === "bigabid") {
302
+ trackBigabidComplete();
303
+ }
304
+ if (AD_NETWORK === "inmobi") {
305
+ trackInMobiEvent("Gameplay_Complete");
306
+ clearInMobiDurationTracking();
307
+ }
308
+ if (AD_NETWORK === "applovin") {
309
+ trackApplovinEvent("ENDCARD_SHOWN");
310
+ }
311
+ });
312
+ sdk.on("install", () => {
313
+ if (AD_NETWORK === "bigabid") {
314
+ trackBigabidEvent("click");
315
+ }
316
+ if (AD_NETWORK === "inmobi") {
317
+ trackInMobiEvent("DSP_Click");
318
+ clearInMobiDurationTracking();
319
+ }
320
+ if (AD_NETWORK === "applovin") {
321
+ trackApplovinEvent("CTA_CLICKED");
322
+ }
323
+ });
324
+ sdk.once("retry", () => {
325
+ if (AD_NETWORK === "applovin") {
326
+ trackApplovinEvent("CHALLENGE_RETRY");
327
+ }
328
+ });
208
329
  }
209
330
 
210
331
  // src/assets/images.ts
@@ -483,7 +604,7 @@ var initCallback = () => {
483
604
  };
484
605
  function bootAd() {
485
606
  if (sdk.isReady) return;
486
- emitEvent("boot");
607
+ emitEvent("init");
487
608
  document.body.oncontextmenu = function() {
488
609
  return false;
489
610
  };
@@ -800,7 +921,6 @@ function initSDK() {
800
921
  } else {
801
922
  startDefaultProtocol();
802
923
  }
803
- emitEvent("init");
804
924
  }
805
925
  var _sdk = class _sdk {
806
926
  /**
@@ -808,6 +928,12 @@ var _sdk = class _sdk {
808
928
  * This must be called as earlier as possible.
809
929
  *
810
930
  * @param callback Optional function called when ad container is ready
931
+ * @param options Optional configuration options
932
+ * @param options.totalSuccessCount Total number of successful actions expected for progress tracking.
933
+ * When set, the SDK will track success progress as a percentage and trigger
934
+ * channel-specific milestone events (e.g., AppLovin: CHALLENGE_PASS_25/50/75, CHALLENGE_SOLVED).
935
+ * Different channels monitor different percentage thresholds independently.
936
+ * Set to 0 or omit to disable progress tracking.
811
937
  * @example
812
938
  * // Basic initialization
813
939
  * sdk.init();
@@ -817,13 +943,20 @@ var _sdk = class _sdk {
817
943
  * new App(width, height)
818
944
  * });
819
945
  *
820
- * @fires init When initialization starts
821
- * @fires boot When the ad begins booting
822
- * @fires ready When Ad Network is ready and playable ad can be initialized
946
+ * // Initialization with success count progress tracking
947
+ * sdk.init((width, height) => {
948
+ * new App(width, height)
949
+ * }, { totalSuccessCount: 20 });
950
+ *
951
+ * @fires loading When SDK initialization starts
952
+ * @fires loaded When game instance is created and ready to load resources
823
953
  */
824
- static init(callback) {
954
+ static init(callback, options) {
825
955
  if (isSDKInitialized) return;
826
956
  if (callback) initCallback = callback;
957
+ if ((options == null ? void 0 : options.totalSuccessCount) && options.totalSuccessCount > 0) {
958
+ setTotalInteractions(options.totalSuccessCount);
959
+ }
827
960
  initTrackingProtocols();
828
961
  document.readyState === "loading" ? window.addEventListener("DOMContentLoaded", initSDK) : initSDK();
829
962
  isSDKInitialized = true;
@@ -863,6 +996,22 @@ var _sdk = class _sdk {
863
996
  _sdk.resize();
864
997
  }
865
998
  }
999
+ /**
1000
+ * Marks the main scene as fully loaded and ready for user interaction.
1001
+ * Should be called at the end of your main game scene's create() method.
1002
+ *
1003
+ * @example
1004
+ * // In Phaser MainScene.create()
1005
+ * create() {
1006
+ * // ... all initialization code ...
1007
+ * sdk.interactive();
1008
+ * }
1009
+ *
1010
+ * @fires interactive When the main scene is ready for user interaction
1011
+ */
1012
+ static interactive() {
1013
+ emitEvent("interactive");
1014
+ }
866
1015
  /**
867
1016
  * Marks the playable ad as finished.
868
1017
  * This triggers network-specific completion handlers.
@@ -1037,6 +1186,60 @@ var _sdk = class _sdk {
1037
1186
  static resize() {
1038
1187
  handleResize(_sdk.maxWidth, _sdk.maxHeight);
1039
1188
  }
1189
+ /**
1190
+ * Records successful game actions (e.g., successful match, level clear).
1191
+ * This should be called by game logic when a meaningful success occurs.
1192
+ * This count is used for progress tracking (e.g., AppLovin milestone events).
1193
+ *
1194
+ * @param count Optional success count to add (default: 1)
1195
+ *
1196
+ * @example
1197
+ * // Record single success when match completes
1198
+ * onMatchSuccess() {
1199
+ * sdk.recordSuccessCount();
1200
+ * }
1201
+ *
1202
+ * // Record multiple successes at once
1203
+ * onComboMatch(comboCount) {
1204
+ * sdk.recordSuccessCount(comboCount);
1205
+ * }
1206
+ *
1207
+ * @fires success With updated success count (triggers progress tracking)
1208
+ */
1209
+ static recordSuccessCount(count = 1) {
1210
+ _sdk.successCount += count;
1211
+ emitEvent("success", _sdk.successCount);
1212
+ }
1213
+ /**
1214
+ * Records a game success/completion event.
1215
+ * Sends platform-specific success tracking events:
1216
+ * - AppLovin: CHALLENGE_SOLVED
1217
+ * - Bigabid: complete
1218
+ * - InMobi: Gameplay_Complete
1219
+ *
1220
+ * @example
1221
+ * // When player completes the level
1222
+ * onLevelComplete() {
1223
+ * sdk.recordSuccess();
1224
+ * }
1225
+ */
1226
+ static recordSuccess() {
1227
+ trackChallengeSuccess();
1228
+ }
1229
+ /**
1230
+ * Records a game failure event.
1231
+ * Sends platform-specific failure tracking events:
1232
+ * - AppLovin: CHALLENGE_FAILED
1233
+ *
1234
+ * @example
1235
+ * // When player fails the level
1236
+ * onLevelFailed() {
1237
+ * sdk.recordFailed();
1238
+ * }
1239
+ */
1240
+ static recordFailed() {
1241
+ trackChallengeFailed();
1242
+ }
1040
1243
  /**
1041
1244
  * Forces the playable ad into a paused state.
1042
1245
  *
@@ -1130,9 +1333,15 @@ var _sdk = class _sdk {
1130
1333
  static getCurChannel() {
1131
1334
  return AD_NETWORK;
1132
1335
  }
1336
+ /**
1337
+ * 判断是否是 Google
1338
+ */
1339
+ static isGoogle() {
1340
+ return _sdk.getCurChannel() === "google";
1341
+ }
1133
1342
  };
1134
1343
  /** Current version of the SDK */
1135
- _sdk.version = "1.0.24";
1344
+ _sdk.version = "1.0.26";
1136
1345
  /** Current maximum width of the playable ad container in pixels */
1137
1346
  _sdk.maxWidth = Math.floor(window.innerWidth);
1138
1347
  /** Current maximum height of the playable ad container in pixels */
@@ -1149,8 +1358,12 @@ _sdk.isPaused = false;
1149
1358
  _sdk.isFinished = false;
1150
1359
  /** Current volume level (0-1) */
1151
1360
  _sdk.volume = actualVolume;
1152
- /** Number of user interactions with the playable ad */
1361
+ /** Number of user interactions with the playable ad (auto-incremented on each touch/click) */
1153
1362
  _sdk.interactions = 0;
1363
+ /** Number of successful game actions (e.g., successful matches, level clears).
1364
+ * Controlled by calling sdk.recordSuccessCount(), NOT auto-incremented.
1365
+ */
1366
+ _sdk.successCount = 0;
1154
1367
  var sdk = _sdk;
1155
1368
  window["console"].log(
1156
1369
  `%c @tencent/playable-sdk %c v${sdk.version} `,