@playcraft/adsdk 1.0.11 → 1.0.13-beta.1

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.
@@ -159,7 +159,7 @@
159
159
  }
160
160
  }
161
161
 
162
- // src/tracking.ts
162
+ // node_modules/@playcraft/ads-tracking/dist/esm/index.js
163
163
  function getCurrentAdNetwork(adNetwork) {
164
164
  const network = adNetwork || (typeof AD_NETWORK !== "undefined" ? AD_NETWORK : "");
165
165
  const supportedNetworks = ["bigabid", "inmobi", "applovin"];
@@ -175,19 +175,19 @@
175
175
  }
176
176
  }
177
177
  function trackBigabidEvent(event) {
178
- console.log(" trackBigabidEvent", event);
178
+ console.log("trackBigabidEvent", event);
179
179
  if (window.BIGABID_BIDTIMEMACROS && window.BIGABID_BIDTIMEMACROS[event]) {
180
180
  trackURL(window.BIGABID_BIDTIMEMACROS[event]);
181
181
  }
182
182
  }
183
183
  function trackInMobiEvent(event) {
184
- console.log(" trackInMobiEvent", event);
184
+ console.log("trackInMobiEvent", event);
185
185
  if (window.INMOBI_DSPMACROS && window.INMOBI_DSPMACROS[event]) {
186
186
  trackURL(window.INMOBI_DSPMACROS[event]);
187
187
  }
188
188
  }
189
189
  function trackApplovinEvent(event) {
190
- console.log(" trackApplovinEvent", event);
190
+ console.log("trackApplovinEvent", event);
191
191
  if (typeof window.ALPlayableAnalytics !== "undefined") {
192
192
  window.ALPlayableAnalytics.trackEvent(event);
193
193
  }
@@ -213,13 +213,8 @@
213
213
  }
214
214
  inmobiTimers = [];
215
215
  }
216
- var totalInteractions = 0;
217
216
  var progressMilestones = [];
218
- function setTotalInteractions(total) {
219
- totalInteractions = total;
220
- }
221
217
  function initProgressMilestones(adNetwork) {
222
- if (totalInteractions <= 0) return;
223
218
  const network = getCurrentAdNetwork(adNetwork);
224
219
  if (!network) return;
225
220
  if (network === "applovin") {
@@ -227,25 +222,25 @@
227
222
  { percent: 25, triggered: false, callback: () => trackApplovinEvent("CHALLENGE_PASS_25") },
228
223
  { percent: 50, triggered: false, callback: () => trackApplovinEvent("CHALLENGE_PASS_50") },
229
224
  { percent: 75, triggered: false, callback: () => trackApplovinEvent("CHALLENGE_PASS_75") },
230
- { percent: 100, triggered: false, callback: () => _trackChallengeSuccess(adNetwork) }
225
+ { percent: 100, triggered: false, callback: () => onPlaycraftChallengeSuccess(adNetwork) }
231
226
  ];
232
227
  } else if (network === "bigabid") {
233
228
  progressMilestones = [
234
- { percent: 100, triggered: false, callback: () => _trackChallengeSuccess(adNetwork) }
229
+ { percent: 100, triggered: false, callback: () => onPlaycraftChallengeSuccess(adNetwork) }
235
230
  ];
236
231
  }
237
232
  }
238
- function checkInteractionProgress(currentInteractions) {
239
- if (totalInteractions <= 0 || progressMilestones.length === 0) return;
240
- const currentPercent = currentInteractions / totalInteractions * 100;
233
+ function onPlaycraftChallengeProgress(percent) {
234
+ if (progressMilestones.length === 0) return;
235
+ const clampedPercent = Math.min(100, Math.max(0, percent));
241
236
  for (const milestone of progressMilestones) {
242
- if (!milestone.triggered && currentPercent >= milestone.percent) {
237
+ if (!milestone.triggered && clampedPercent >= milestone.percent) {
243
238
  milestone.triggered = true;
244
239
  milestone.callback();
245
240
  }
246
241
  }
247
242
  }
248
- function _onInit(adNetwork) {
243
+ function onPlaycraftTrackingInit(adNetwork) {
249
244
  initProgressMilestones(adNetwork);
250
245
  const network = getCurrentAdNetwork(adNetwork);
251
246
  if (!network) return;
@@ -259,7 +254,7 @@
259
254
  trackApplovinEvent("LOADING");
260
255
  }
261
256
  }
262
- function _onStart(adNetwork) {
257
+ function onPlaycraftTrackingLoading(adNetwork) {
263
258
  const network = getCurrentAdNetwork(adNetwork);
264
259
  if (!network) return;
265
260
  if (network === "bigabid") {
@@ -273,14 +268,14 @@
273
268
  trackApplovinEvent("LOADED");
274
269
  }
275
270
  }
276
- function _onInteractive(adNetwork) {
271
+ function onPlaycraftTrackingLoaded(adNetwork) {
277
272
  const network = getCurrentAdNetwork(adNetwork);
278
273
  if (!network) return;
279
274
  if (network === "applovin") {
280
275
  trackApplovinEvent("DISPLAYED");
281
276
  }
282
277
  }
283
- function _onInteraction(adNetwork) {
278
+ function onPlaycraftChallengeStart(adNetwork) {
284
279
  const network = getCurrentAdNetwork(adNetwork);
285
280
  if (!network) return;
286
281
  if (network === "bigabid") {
@@ -293,10 +288,20 @@
293
288
  trackApplovinEvent("CHALLENGE_STARTED");
294
289
  }
295
290
  }
296
- function _onSuccess(successCount) {
297
- checkInteractionProgress(successCount);
291
+ function onPlaycraftChallengeSuccess(adNetwork) {
292
+ const network = getCurrentAdNetwork(adNetwork);
293
+ if (!network) return;
294
+ if (network === "applovin") {
295
+ trackApplovinEvent("CHALLENGE_SOLVED");
296
+ }
297
+ if (network === "bigabid") {
298
+ trackBigabidComplete();
299
+ }
300
+ if (network === "inmobi") {
301
+ trackInMobiEvent("Gameplay_Complete");
302
+ }
298
303
  }
299
- function _onFinish(adNetwork) {
304
+ function onPlaycraftChallengeFinish(adNetwork) {
300
305
  const network = getCurrentAdNetwork(adNetwork);
301
306
  if (!network) return;
302
307
  if (network === "bigabid") {
@@ -310,7 +315,7 @@
310
315
  trackApplovinEvent("ENDCARD_SHOWN");
311
316
  }
312
317
  }
313
- function _onInstall(adNetwork) {
318
+ function onPlaycraftInstall(adNetwork) {
314
319
  const network = getCurrentAdNetwork(adNetwork);
315
320
  if (!network) return;
316
321
  if (network === "bigabid") {
@@ -324,27 +329,14 @@
324
329
  trackApplovinEvent("CTA_CLICKED");
325
330
  }
326
331
  }
327
- function _onRetry(adNetwork) {
332
+ function onPlaycraftRetry(adNetwork) {
328
333
  const network = getCurrentAdNetwork(adNetwork);
329
334
  if (!network) return;
330
335
  if (network === "applovin") {
331
336
  trackApplovinEvent("CHALLENGE_RETRY");
332
337
  }
333
338
  }
334
- function _trackChallengeSuccess(adNetwork) {
335
- const network = getCurrentAdNetwork(adNetwork);
336
- if (!network) return;
337
- if (network === "applovin") {
338
- trackApplovinEvent("CHALLENGE_SOLVED");
339
- }
340
- if (network === "bigabid") {
341
- trackBigabidComplete();
342
- }
343
- if (network === "inmobi") {
344
- trackInMobiEvent("Gameplay_Complete");
345
- }
346
- }
347
- function _trackChallengeFailed(adNetwork) {
339
+ function onPlaycraftChallengeFailed(adNetwork) {
348
340
  const network = getCurrentAdNetwork(adNetwork);
349
341
  if (!network) return;
350
342
  if (network === "applovin") {
@@ -353,65 +345,55 @@
353
345
  }
354
346
  var tracking = {
355
347
  /**
356
- * SDK 初始化开始
348
+ * SDK 初始化开始,同时初始化进度里程碑
357
349
  * @param adNetwork - 可选的广告渠道名称
358
350
  */
359
- onInit: _onInit,
351
+ onPlaycraftTrackingInit,
360
352
  /**
361
- * 游戏资源加载完成
353
+ * 游戏资源加载中
362
354
  * @param adNetwork - 可选的广告渠道名称
363
355
  */
364
- onStart: _onStart,
356
+ onPlaycraftTrackingLoading,
365
357
  /**
366
- * 主场景就绪,用户可交互
358
+ * 游戏资源加载完成、主场景就绪
367
359
  * @param adNetwork - 可选的广告渠道名称
368
360
  */
369
- onInteractive: _onInteractive,
361
+ onPlaycraftTrackingLoaded,
370
362
  /**
371
- * 首次交互
363
+ * 游戏挑战开始(首次用户交互)
372
364
  * @param adNetwork - 可选的广告渠道名称
373
365
  */
374
- onInteraction: _onInteraction,
366
+ onPlaycraftChallengeStart,
375
367
  /**
376
- * 成功计数(用于进度百分比追踪)
377
- * @param successCount - 当前成功次数
368
+ * 上报游戏挑战进度(0-100),内部自动触发对应里程碑,不重复上报
369
+ * @param percent - 当前进度百分比(0-100)
378
370
  */
379
- onSuccess: _onSuccess,
371
+ onPlaycraftChallengeProgress,
380
372
  /**
381
- * 游戏结束
373
+ * 游戏挑战成功
382
374
  * @param adNetwork - 可选的广告渠道名称
383
375
  */
384
- onFinish: _onFinish,
376
+ onPlaycraftChallengeSuccess,
385
377
  /**
386
- * 点击安装
378
+ * 游戏结束
387
379
  * @param adNetwork - 可选的广告渠道名称
388
380
  */
389
- onInstall: _onInstall,
381
+ onPlaycraftChallengeFinish,
390
382
  /**
391
- * 重试游戏
383
+ * 点击安装
392
384
  * @param adNetwork - 可选的广告渠道名称
393
385
  */
394
- onRetry: _onRetry,
395
- /**
396
- * 设置交互总数(用于进度百分比计算)
397
- * @param total - 交互总数
398
- */
399
- setTotalInteractions,
400
- /**
401
- * 检查交互进度
402
- * @param currentInteractions - 当前交互次数
403
- */
404
- checkInteractionProgress,
386
+ onPlaycraftInstall,
405
387
  /**
406
- * 触发游戏成功事件
388
+ * 重试游戏
407
389
  * @param adNetwork - 可选的广告渠道名称
408
390
  */
409
- trackChallengeSuccess: _trackChallengeSuccess,
391
+ onPlaycraftRetry,
410
392
  /**
411
- * 触发游戏失败事件
393
+ * 游戏挑战失败
412
394
  * @param adNetwork - 可选的广告渠道名称
413
395
  */
414
- trackChallengeFailed: _trackChallengeFailed
396
+ onPlaycraftChallengeFailed
415
397
  };
416
398
 
417
399
  // src/tracking-init.ts
@@ -420,14 +402,16 @@
420
402
  if (!supportedNetworks.includes(AD_NETWORK)) {
421
403
  return;
422
404
  }
423
- sdk.once("init", tracking.onInit);
424
- sdk.once("start", tracking.onStart);
425
- sdk.once("interactive", tracking.onInteractive);
426
- sdk.once("interaction", tracking.onInteraction);
427
- sdk.on("success", tracking.onSuccess);
428
- sdk.once("finish", tracking.onFinish);
429
- sdk.on("install", tracking.onInstall);
430
- sdk.once("retry", tracking.onRetry);
405
+ sdk.once("playcraftInit", tracking.onPlaycraftTrackingInit);
406
+ sdk.once("playcraftStart", tracking.onPlaycraftTrackingLoading);
407
+ sdk.once("playcraftInteractive", tracking.onPlaycraftTrackingLoaded);
408
+ sdk.on("playcraftChallengeStart", tracking.onPlaycraftChallengeStart);
409
+ sdk.on("playcraftChallengeProgress", tracking.onPlaycraftChallengeProgress);
410
+ sdk.once("playcraftFinish", tracking.onPlaycraftChallengeFinish);
411
+ sdk.on("playcraftInstall", tracking.onPlaycraftInstall);
412
+ sdk.once("playcraftRetry", tracking.onPlaycraftRetry);
413
+ sdk.on("playcraftChallengeSuccess", tracking.onPlaycraftChallengeSuccess);
414
+ sdk.on("playcraftChallengeFailed", tracking.onPlaycraftChallengeFailed);
431
415
  }
432
416
 
433
417
  // src/assets/images.ts
@@ -695,6 +679,73 @@
695
679
  }
696
680
  }
697
681
 
682
+ // src/theme-config.ts
683
+ function extractDefaultsFromSchema(schema) {
684
+ if (!schema || typeof schema !== "object") return void 0;
685
+ if (schema.type === "object" && schema.properties) {
686
+ const result = {};
687
+ for (const [key, propSchema] of Object.entries(schema.properties)) {
688
+ const val = extractDefaultsFromSchema(propSchema);
689
+ if (val !== void 0) {
690
+ result[key] = val;
691
+ }
692
+ }
693
+ return Object.keys(result).length > 0 ? result : void 0;
694
+ }
695
+ if ("default" in schema) {
696
+ return schema.default;
697
+ }
698
+ return void 0;
699
+ }
700
+ function resolveImagePaths(config, assetRecordByPath) {
701
+ if (!assetRecordByPath || !config || typeof config !== "object") return;
702
+ for (const key of Object.keys(config)) {
703
+ const value = config[key];
704
+ if (typeof value === "string") {
705
+ if (assetRecordByPath[value]) {
706
+ config[key] = assetRecordByPath[value];
707
+ }
708
+ } else if (value !== null && typeof value === "object" && !Array.isArray(value)) {
709
+ resolveImagePaths(value, assetRecordByPath);
710
+ }
711
+ }
712
+ }
713
+ var _cachedConfig = null;
714
+ function deepMerge(target, source) {
715
+ for (const key of Object.keys(source)) {
716
+ const srcVal = source[key];
717
+ const tgtVal = target[key];
718
+ if (srcVal !== null && typeof srcVal === "object" && !Array.isArray(srcVal) && tgtVal !== null && typeof tgtVal === "object" && !Array.isArray(tgtVal)) {
719
+ deepMerge(tgtVal, srcVal);
720
+ } else if (srcVal !== void 0) {
721
+ target[key] = srcVal;
722
+ }
723
+ }
724
+ return target;
725
+ }
726
+ function setConfig(configList, config) {
727
+ const { assetRecordByPath } = config;
728
+ const resolvedConfigs = configList.map((item) => {
729
+ var _a;
730
+ if (!item) return {};
731
+ return item.$schema ? (_a = extractDefaultsFromSchema(item)) != null ? _a : {} : item;
732
+ });
733
+ const [first, ...rest] = resolvedConfigs;
734
+ const mergedConfig = JSON.parse(JSON.stringify(first));
735
+ for (const data of rest) {
736
+ deepMerge(mergedConfig, data);
737
+ }
738
+ resolveImagePaths(mergedConfig, assetRecordByPath);
739
+ _cachedConfig = mergedConfig;
740
+ }
741
+ function getConfig() {
742
+ if (!_cachedConfig) {
743
+ console.warn("[PlayableSDK] Theme config not initialized. Call setConfig() first.");
744
+ return {};
745
+ }
746
+ return _cachedConfig;
747
+ }
748
+
698
749
  // src/core.ts
699
750
  var destinationUrl = "";
700
751
  var isSDKInitialized = false;
@@ -706,16 +757,16 @@
706
757
  };
707
758
  function bootAd() {
708
759
  if (sdk.isReady) return;
709
- emitEvent("init");
760
+ emitEvent("playcraftInit");
710
761
  document.body.oncontextmenu = function() {
711
762
  return false;
712
763
  };
713
764
  initCallback(sdk.maxWidth, sdk.maxHeight);
714
- emitEvent("ready");
765
+ emitEvent("playcraftReady");
715
766
  sdk.isReady = true;
716
767
  }
717
768
  function fireVolumeChange(value) {
718
- emitEvent("volume", value);
769
+ emitEvent("playcraftVolume", value);
719
770
  }
720
771
  function changeVolume(value) {
721
772
  sdk.volume = value;
@@ -728,13 +779,13 @@
728
779
  function handlePause() {
729
780
  changeVolume(0);
730
781
  sdk.isPaused = true;
731
- emitEvent("pause");
782
+ emitEvent("playcraftPause");
732
783
  }
733
784
  function handleResume() {
734
785
  if (isForcePaused) return;
735
786
  changeVolume(actualVolume);
736
787
  sdk.isPaused = false;
737
- emitEvent("resume");
788
+ emitEvent("playcraftResume");
738
789
  }
739
790
  function fireResizeEvent(width, height) {
740
791
  handleResize(width, height);
@@ -917,7 +968,7 @@
917
968
  const tapjoyApi = {
918
969
  skipAd: function() {
919
970
  try {
920
- sdk.finish();
971
+ sdk.playcraftFinish();
921
972
  } catch (e) {
922
973
  console.warn("Could not skip ad! | " + e);
923
974
  }
@@ -936,7 +987,7 @@
936
987
  sdk.maxWidth = Math.floor(width || window.innerWidth);
937
988
  sdk.maxHeight = Math.floor(height || window.innerHeight);
938
989
  sdk.isLandscape = sdk.maxWidth > sdk.maxHeight;
939
- emitEvent("resize", sdk.maxWidth, sdk.maxHeight);
990
+ emitEvent("playcraftResize", sdk.maxWidth, sdk.maxHeight);
940
991
  }
941
992
  var isListeningToTouchEvents = false;
942
993
  var isTouchEventRegistered = false;
@@ -946,7 +997,7 @@
946
997
  }
947
998
  if (isListeningToTouchEvents && event instanceof MouseEvent) return;
948
999
  sdk.interactions += 1;
949
- emitEvent("interaction", sdk.interactions);
1000
+ emitEvent("playcraftInteraction", sdk.interactions);
950
1001
  }
951
1002
  function registerTouchHandlers() {
952
1003
  if (!isTouchEventRegistered) {
@@ -1030,35 +1081,21 @@
1030
1081
  * This must be called as earlier as possible.
1031
1082
  *
1032
1083
  * @param callback Optional function called when ad container is ready
1033
- * @param options Optional configuration options
1034
- * @param options.totalSuccessCount Total number of successful actions expected for progress tracking.
1035
- * When set, the SDK will track success progress as a percentage and trigger
1036
- * channel-specific milestone events (e.g., AppLovin: CHALLENGE_PASS_25/50/75, CHALLENGE_SOLVED).
1037
- * Different channels monitor different percentage thresholds independently.
1038
- * Set to 0 or omit to disable progress tracking.
1039
1084
  * @example
1040
1085
  * // Basic initialization
1041
- * sdk.init();
1086
+ * sdk.playcraftInit();
1042
1087
  *
1043
1088
  * // Initialization with callback
1044
- * sdk.init((width, height) => {
1089
+ * sdk.playcraftInit((width, height) => {
1045
1090
  * new App(width, height)
1046
1091
  * });
1047
1092
  *
1048
- * // Initialization with success count progress tracking
1049
- * sdk.init((width, height) => {
1050
- * new App(width, height)
1051
- * }, { totalSuccessCount: 20 });
1052
- *
1053
- * @fires loading When SDK initialization starts
1054
- * @fires loaded When game instance is created and ready to load resources
1093
+ * @fires playcraftInit When SDK initialization starts
1094
+ * @fires playcraftReady When game instance is created and ready to load resources
1055
1095
  */
1056
- static init(callback, options) {
1096
+ static playcraftInit(callback) {
1057
1097
  if (isSDKInitialized) return;
1058
1098
  if (callback) initCallback = callback;
1059
- if ((options == null ? void 0 : options.totalSuccessCount) && options.totalSuccessCount > 0) {
1060
- tracking.setTotalInteractions(options.totalSuccessCount);
1061
- }
1062
1099
  initTrackingProtocols();
1063
1100
  document.readyState === "loading" ? window.addEventListener("DOMContentLoaded", initSDK) : initSDK();
1064
1101
  isSDKInitialized = true;
@@ -1068,25 +1105,24 @@
1068
1105
  * Should be called after all resources are loaded and first frame is rendered.
1069
1106
  *
1070
1107
  * @example
1071
- * // Call just after all resources are preloaded and first frame is rendered
1072
- * sdk.start();
1108
+ * sdk.playcraftStart();
1073
1109
  *
1074
- * @fires start When the playable ad starts
1075
- * @fires resize When the ad container is initially sized
1110
+ * @fires playcraftStart When the playable ad starts
1111
+ * @fires playcraftResize When the ad container is initially sized
1076
1112
  */
1077
- static start() {
1113
+ static playcraftStart() {
1078
1114
  if (_sdk.isStarted) return;
1079
1115
  _sdk.isStarted = true;
1080
- emitEvent("start");
1116
+ emitEvent("playcraftStart");
1081
1117
  registerTouchHandlers();
1082
1118
  if ("mintegral" === AD_NETWORK && isMintegral()) {
1083
- _sdk.resize();
1119
+ _sdk.playcraftResize();
1084
1120
  handlePause();
1085
1121
  window.gameReady && window.gameReady();
1086
1122
  } else if ("bigoads" === AD_NETWORK && isBigoAds()) {
1087
1123
  window.BGY_MRAID && window.BGY_MRAID.gameReady && window.BGY_MRAID.gameReady();
1088
1124
  fireVolumeChange(_sdk.volume);
1089
- _sdk.resize();
1125
+ _sdk.playcraftResize();
1090
1126
  } else {
1091
1127
  if ("tapjoy" === AD_NETWORK && isTapjoy()) {
1092
1128
  window.TJ_API.setPlayableBuild({
@@ -1095,7 +1131,7 @@
1095
1131
  });
1096
1132
  }
1097
1133
  fireVolumeChange(_sdk.volume);
1098
- _sdk.resize();
1134
+ _sdk.playcraftResize();
1099
1135
  }
1100
1136
  }
1101
1137
  /**
@@ -1103,28 +1139,39 @@
1103
1139
  * Should be called at the end of your main game scene's create() method.
1104
1140
  *
1105
1141
  * @example
1106
- * // In Phaser MainScene.create()
1107
1142
  * create() {
1108
1143
  * // ... all initialization code ...
1109
- * sdk.interactive();
1144
+ * sdk.playcraftInteractive();
1110
1145
  * }
1111
1146
  *
1112
- * @fires interactive When the main scene is ready for user interaction
1147
+ * @fires playcraftInteractive When the main scene is ready for user interaction
1113
1148
  */
1114
- static interactive() {
1115
- emitEvent("interactive");
1149
+ static playcraftInteractive() {
1150
+ emitEvent("playcraftInteractive");
1151
+ }
1152
+ /**
1153
+ * Marks the challenge as started.
1154
+ * Should be called by business logic when the user actually starts playing.
1155
+ *
1156
+ * @example
1157
+ * onFirstClick() {
1158
+ * sdk.playcraftChallengeStart();
1159
+ * }
1160
+ *
1161
+ * @fires playcraftChallengeStart When the challenge starts
1162
+ */
1163
+ static playcraftChallengeStart() {
1164
+ emitEvent("playcraftChallengeStart");
1116
1165
  }
1117
1166
  /**
1118
1167
  * Marks the playable ad as finished.
1119
- * This triggers network-specific completion handlers.
1120
1168
  *
1121
1169
  * @example
1122
- * // Call when game/experience is complete
1123
- * sdk.finish();
1170
+ * sdk.playcraftFinish();
1124
1171
  *
1125
- * @fires finish When the playable ad is marked as finished
1172
+ * @fires playcraftFinish When the playable ad is marked as finished
1126
1173
  */
1127
- static finish() {
1174
+ static playcraftFinish() {
1128
1175
  _sdk.isFinished = true;
1129
1176
  if ("tapjoy" === AD_NETWORK && isTapjoy()) {
1130
1177
  finishTapjoy();
@@ -1144,38 +1191,34 @@
1144
1191
  console.warn("Could not call mraid.close():", e);
1145
1192
  }
1146
1193
  }
1147
- emitEvent("finish");
1194
+ emitEvent("playcraftFinish");
1148
1195
  }
1149
1196
  /**
1150
1197
  * Triggers a retry/restart of the playable ad.
1151
- * Behavior varies by ad network.
1152
1198
  *
1153
1199
  * @example
1154
- * // Allow user to try again
1155
- * retryButton.onclick = () => sdk.retry();
1200
+ * retryButton.onclick = () => sdk.playcraftRetry();
1156
1201
  *
1157
- * @fires retry When a retry is triggered
1202
+ * @fires playcraftRetry When a retry is triggered
1158
1203
  */
1159
- static retry() {
1204
+ static playcraftRetry() {
1160
1205
  if ("mintegral" === AD_NETWORK && isMintegral()) {
1161
1206
  } else if ("nucleo" === AD_PROTOCOL && isNucleo()) {
1162
1207
  NUC.trigger.tryAgain();
1163
1208
  }
1164
- emitEvent("retry");
1209
+ emitEvent("playcraftRetry");
1165
1210
  }
1166
1211
  /**
1167
1212
  * Triggers the install/download action for the advertised app.
1168
- * Handles different store opening methods across ad networks.
1169
1213
  *
1170
1214
  * @example
1171
- * // Call when user wants to install
1172
- * installButton.onclick = () => sdk.install();
1215
+ * installButton.onclick = () => sdk.playcraftInstall();
1173
1216
  *
1174
- * @fires finish If the ad hasn't been marked as finished
1175
- * @fires install When the install action is triggered
1217
+ * @fires playcraftFinish If the ad hasn't been marked as finished
1218
+ * @fires playcraftInstall When the install action is triggered
1176
1219
  */
1177
- static install(params) {
1178
- console.log("[SDK] install() called, interactions:", _sdk.interactions, "isFinished:", _sdk.isFinished, "isInstallClicked:", isInstallClicked);
1220
+ static playcraftInstall(params) {
1221
+ console.log("[SDK] playcraftInstall() called, interactions:", _sdk.interactions, "isFinished:", _sdk.isFinished, "isInstallClicked:", isInstallClicked);
1179
1222
  if (_sdk.interactions < 1 && isDisableFirstClickToOpenApp()) {
1180
1223
  console.log("[SDK] \u9996\u6B21\u70B9\u51FB\u4FDD\u62A4\uFF0C\u76F4\u63A5\u8FD4\u56DE");
1181
1224
  return;
@@ -1185,23 +1228,23 @@
1185
1228
  return;
1186
1229
  }
1187
1230
  const timeout = setTimeout(function() {
1188
- _sdk.install();
1231
+ _sdk.playcraftInstall();
1189
1232
  clearTimeout(timeout);
1190
1233
  }, params.timeout || 3e3);
1191
1234
  return;
1192
1235
  }
1193
1236
  if (!_sdk.isFinished) {
1194
- console.log("[SDK] \u9996\u6B21\u6267\u884C install\uFF0C\u89E6\u53D1 finish \u4E8B\u4EF6");
1237
+ console.log("[SDK] \u9996\u6B21\u6267\u884C playcraftInstall\uFF0C\u89E6\u53D1 playcraftFinish \u4E8B\u4EF6");
1195
1238
  _sdk.isFinished = true;
1196
1239
  let timeout = 0;
1197
1240
  if ("tapjoy" === AD_NETWORK && isTapjoy()) {
1198
1241
  finishTapjoy();
1199
1242
  timeout = 300;
1200
1243
  }
1201
- emitEvent("finish");
1244
+ emitEvent("playcraftFinish");
1202
1245
  setTimeout(function() {
1203
- console.log("[SDK] \u5F02\u6B65\u9012\u5F52\u8C03\u7528 install()");
1204
- _sdk.install();
1246
+ console.log("[SDK] \u5F02\u6B65\u9012\u5F52\u8C03\u7528 playcraftInstall()");
1247
+ _sdk.playcraftInstall();
1205
1248
  }, timeout);
1206
1249
  return;
1207
1250
  }
@@ -1214,7 +1257,7 @@
1214
1257
  isInstallClicked = false;
1215
1258
  console.log("[SDK] \u9632\u6296\u89E3\u9501");
1216
1259
  }, 500);
1217
- emitEvent("install");
1260
+ emitEvent("playcraftInstall");
1218
1261
  console.log("Ad_Protocal: ", AD_PROTOCOL);
1219
1262
  if ("mraid" === AD_PROTOCOL && isMraid()) {
1220
1263
  try {
@@ -1278,39 +1321,30 @@
1278
1321
  }
1279
1322
  /**
1280
1323
  * Trigger force resize event
1281
- * Useful when container size changes need to be manually propagated.
1282
1324
  *
1283
1325
  * @example
1284
- * sdk.resize();
1326
+ * sdk.playcraftResize();
1285
1327
  *
1286
- * @fires resize With current maxWidth and maxHeight
1328
+ * @fires playcraftResize With current maxWidth and maxHeight
1287
1329
  */
1288
- static resize() {
1330
+ static playcraftResize() {
1289
1331
  handleResize(_sdk.maxWidth, _sdk.maxHeight);
1290
1332
  }
1291
1333
  /**
1292
- * Records successful game actions (e.g., successful match, level clear).
1293
- * This should be called by game logic when a meaningful success occurs.
1294
- * This count is used for progress tracking (e.g., AppLovin milestone events).
1334
+ * Records playable ad challenge progress (0-100).
1335
+ * Triggers channel-specific milestone events based on the progress value.
1336
+ * Milestones are not re-triggered once fired.
1337
+ *
1338
+ * @param percent Progress percentage (0-100)
1295
1339
  *
1296
- * @param count Optional success count to add (default: 1)
1297
- *
1298
1340
  * @example
1299
- * // Record single success when match completes
1300
- * onMatchSuccess() {
1301
- * sdk.recordSuccessCount();
1302
- * }
1303
- *
1304
- * // Record multiple successes at once
1305
- * onComboMatch(comboCount) {
1306
- * sdk.recordSuccessCount(comboCount);
1307
- * }
1341
+ * // Report 50% progress
1342
+ * sdk.recordPlaycraftChallengeProgress(50);
1308
1343
  *
1309
- * @fires success With updated success count (triggers progress tracking)
1344
+ * @fires playcraftChallengeProgress With the progress percentage value
1310
1345
  */
1311
- static recordSuccessCount(count = 1) {
1312
- _sdk.successCount += count;
1313
- emitEvent("success", _sdk.successCount);
1346
+ static recordPlaycraftChallengeProgress(percent) {
1347
+ emitEvent("playcraftChallengeProgress", percent);
1314
1348
  }
1315
1349
  /**
1316
1350
  * Records a game success/completion event.
@@ -1320,13 +1354,12 @@
1320
1354
  * - InMobi: Gameplay_Complete
1321
1355
  *
1322
1356
  * @example
1323
- * // When player completes the level
1324
1357
  * onLevelComplete() {
1325
- * sdk.recordSuccess();
1358
+ * sdk.playcraftRecordSuccess();
1326
1359
  * }
1327
1360
  */
1328
- static recordSuccess() {
1329
- tracking.trackChallengeSuccess();
1361
+ static playcraftRecordSuccess() {
1362
+ emitEvent("playcraftChallengeSuccess");
1330
1363
  }
1331
1364
  /**
1332
1365
  * Records a game failure event.
@@ -1334,24 +1367,22 @@
1334
1367
  * - AppLovin: CHALLENGE_FAILED
1335
1368
  *
1336
1369
  * @example
1337
- * // When player fails the level
1338
1370
  * onLevelFailed() {
1339
- * sdk.recordFailed();
1371
+ * sdk.playcraftRecordFailed();
1340
1372
  * }
1341
1373
  */
1342
- static recordFailed() {
1343
- tracking.trackChallengeFailed();
1374
+ static playcraftRecordFailed() {
1375
+ emitEvent("playcraftChallengeFailed");
1344
1376
  }
1345
1377
  /**
1346
1378
  * Forces the playable ad into a paused state.
1347
1379
  *
1348
1380
  * @example
1349
- * // Pause the experience
1350
- * pauseButton.onclick = () => sdk.pause();
1381
+ * pauseButton.onclick = () => sdk.playcraftPause();
1351
1382
  *
1352
- * @fires pause When the ad enters paused state
1383
+ * @fires playcraftPause When the ad enters paused state
1353
1384
  */
1354
- static pause() {
1385
+ static playcraftPause() {
1355
1386
  if (!isForcePaused) {
1356
1387
  isForcePaused = true;
1357
1388
  handlePause();
@@ -1359,15 +1390,13 @@
1359
1390
  }
1360
1391
  /**
1361
1392
  * Resumes the playable ad from a forced pause state.
1362
- * Only works if the ad was paused via sdk.pause().
1363
1393
  *
1364
1394
  * @example
1365
- * // Resume from pause
1366
- * resumeButton.onclick = () => sdk.resume();
1395
+ * resumeButton.onclick = () => sdk.playcraftResume();
1367
1396
  *
1368
- * @fires resume When the ad resumes from pause
1397
+ * @fires playcraftResume When the ad resumes from pause
1369
1398
  */
1370
- static resume() {
1399
+ static playcraftResume() {
1371
1400
  if (isForcePaused) {
1372
1401
  isForcePaused = false;
1373
1402
  handleResume();
@@ -1381,15 +1410,9 @@
1381
1410
  * @param context Optional 'this' context for the callback
1382
1411
  *
1383
1412
  * @example
1384
- * // Listen for user interactions
1385
- * sdk.on('interaction', (count) => {
1413
+ * sdk.on('playcraftInteraction', (count) => {
1386
1414
  * console.log(`User interaction #${count}`);
1387
1415
  * });
1388
- *
1389
- * // Listen for resize with context
1390
- * sdk.on('resize', function(width, height) {
1391
- * this.updateLayout(width, height);
1392
- * }, gameInstance);
1393
1416
  */
1394
1417
  static on(event, fn, context) {
1395
1418
  onEvent(event, fn, context);
@@ -1402,8 +1425,7 @@
1402
1425
  * @param context Optional 'this' context for the callback
1403
1426
  *
1404
1427
  * @example
1405
- * // Listen for first interaction only
1406
- * sdk.once('interaction', () => {
1428
+ * sdk.once('playcraftInteraction', () => {
1407
1429
  * console.log('First user interaction occurred!');
1408
1430
  * });
1409
1431
  */
@@ -1414,22 +1436,16 @@
1414
1436
  * Removes an event listener.
1415
1437
  *
1416
1438
  * @param event Name of the event to stop listening for
1417
- * @param fn Optional callback function to remove (if not provided, removes all listeners for the event)
1439
+ * @param fn Optional callback function to remove
1418
1440
  * @param context Optional 'this' context to match when removing
1419
1441
  *
1420
1442
  * @example
1421
- * // Remove specific listener
1422
- * const handler = () => console.log('Interaction');
1423
- * sdk.off('interaction', handler);
1424
- *
1425
- * // Remove all listeners for an event
1426
- * sdk.off('interaction');
1443
+ * sdk.off('playcraftInteraction', handler);
1427
1444
  */
1428
1445
  static off(event, fn, context) {
1429
1446
  offEvent(event, fn, context);
1430
1447
  }
1431
1448
  /**
1432
- *
1433
1449
  * @returns 当前渠道
1434
1450
  */
1435
1451
  static getCurChannel() {
@@ -1441,9 +1457,43 @@
1441
1457
  static isGoogle() {
1442
1458
  return _sdk.getCurChannel() === "google";
1443
1459
  }
1460
+ /**
1461
+ * 设置主题配置,支持传入多份 JSON5 配置。
1462
+ * 每一份配置都可以是 JSON Schema(带 $schema 字段),会自动提取其中的 default 值。
1463
+ * 所有配置按顺序依次深度合并,后面的优先级更高。
1464
+ *
1465
+ * @param configList - 配置数组,每一项可以是:
1466
+ * - JSON Schema(带 $schema 字段):自动提取 default 值后参与合并
1467
+ * - 普通配置对象:直接参与合并
1468
+ * @param config - 额外配置项
1469
+ * - config.assetRecordByPath: 相对路径到已解析 URL 的映射
1470
+ *
1471
+ * @example
1472
+ * sdk.setConfig(
1473
+ * [schemaA, schemaB, themeData],
1474
+ * { assetRecordByPath: imageAssets }
1475
+ * );
1476
+ */
1477
+ static setConfig(configList, config) {
1478
+ setConfig(configList, config);
1479
+ }
1480
+ /**
1481
+ * 获取合并后的主题配置。
1482
+ * 返回 schema 默认值与用户主题数据深度合并后的结果。
1483
+ * 必须先调用 sdk.setConfig() 才能使用此方法。
1484
+ *
1485
+ * @returns 合并后的主题配置对象
1486
+ *
1487
+ * @example
1488
+ * const config = sdk.getConfig();
1489
+ * console.log(config.primaryColor); // '#ff0000'
1490
+ */
1491
+ static getConfig() {
1492
+ return getConfig();
1493
+ }
1444
1494
  };
1445
1495
  /** Current version of the SDK */
1446
- _sdk.version = "1.0.10";
1496
+ _sdk.version = "1.0.13-beta.1";
1447
1497
  /** Current maximum width of the playable ad container in pixels */
1448
1498
  _sdk.maxWidth = Math.floor(window.innerWidth);
1449
1499
  /** Current maximum height of the playable ad container in pixels */
@@ -1462,10 +1512,6 @@
1462
1512
  _sdk.volume = actualVolume;
1463
1513
  /** Number of user interactions with the playable ad (auto-incremented on each touch/click) */
1464
1514
  _sdk.interactions = 0;
1465
- /** Number of successful game actions (e.g., successful matches, level clears).
1466
- * Controlled by calling sdk.recordSuccessCount(), NOT auto-incremented.
1467
- */
1468
- _sdk.successCount = 0;
1469
1515
  var sdk = _sdk;
1470
1516
  window["console"].log(
1471
1517
  `%c @playcraft/adsdk %c v${sdk.version} `,