@playcraft/adsdk 1.0.12 → 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.
package/dist/esm/index.js CHANGED
@@ -157,275 +157,23 @@ function ensureProtocol() {
157
157
  }
158
158
  }
159
159
 
160
- // src/tracking.ts
161
- function getCurrentAdNetwork(adNetwork) {
162
- const network = adNetwork || (typeof AD_NETWORK !== "undefined" ? AD_NETWORK : "");
163
- const supportedNetworks = ["bigabid", "inmobi", "applovin"];
164
- if (supportedNetworks.includes(network)) {
165
- return network;
166
- }
167
- return null;
168
- }
169
- function trackURL(url) {
170
- if (url) {
171
- const trackingPixel = new Image();
172
- trackingPixel.src = url;
173
- }
174
- }
175
- function trackBigabidEvent(event) {
176
- console.log(" trackBigabidEvent", event);
177
- if (window.BIGABID_BIDTIMEMACROS && window.BIGABID_BIDTIMEMACROS[event]) {
178
- trackURL(window.BIGABID_BIDTIMEMACROS[event]);
179
- }
180
- }
181
- function trackInMobiEvent(event) {
182
- console.log(" trackInMobiEvent", event);
183
- if (window.INMOBI_DSPMACROS && window.INMOBI_DSPMACROS[event]) {
184
- trackURL(window.INMOBI_DSPMACROS[event]);
185
- }
186
- }
187
- function trackApplovinEvent(event) {
188
- console.log(" trackApplovinEvent", event);
189
- if (typeof window.ALPlayableAnalytics !== "undefined") {
190
- window.ALPlayableAnalytics.trackEvent(event);
191
- }
192
- }
193
- var bigabidCompleteTriggered = false;
194
- function trackBigabidComplete() {
195
- if (!bigabidCompleteTriggered) {
196
- trackBigabidEvent("complete");
197
- bigabidCompleteTriggered = true;
198
- }
199
- }
200
- var inmobiTimers = [];
201
- function startInMobiDurationTracking() {
202
- const durations = [5, 10, 15, 20, 25, 30];
203
- for (const sec of durations) {
204
- const timer = setTimeout(() => trackInMobiEvent(`Spent_${sec}_Seconds`), sec * 1e3);
205
- inmobiTimers.push(timer);
206
- }
207
- }
208
- function clearInMobiDurationTracking() {
209
- for (const timer of inmobiTimers) {
210
- clearTimeout(timer);
211
- }
212
- inmobiTimers = [];
213
- }
214
- var totalInteractions = 0;
215
- var progressMilestones = [];
216
- function setTotalInteractions(total) {
217
- totalInteractions = total;
218
- }
219
- function initProgressMilestones(adNetwork) {
220
- if (totalInteractions <= 0) return;
221
- const network = getCurrentAdNetwork(adNetwork);
222
- if (!network) return;
223
- if (network === "applovin") {
224
- progressMilestones = [
225
- { percent: 25, triggered: false, callback: () => trackApplovinEvent("CHALLENGE_PASS_25") },
226
- { percent: 50, triggered: false, callback: () => trackApplovinEvent("CHALLENGE_PASS_50") },
227
- { percent: 75, triggered: false, callback: () => trackApplovinEvent("CHALLENGE_PASS_75") },
228
- { percent: 100, triggered: false, callback: () => _trackChallengeSuccess(adNetwork) }
229
- ];
230
- } else if (network === "bigabid") {
231
- progressMilestones = [
232
- { percent: 100, triggered: false, callback: () => _trackChallengeSuccess(adNetwork) }
233
- ];
234
- }
235
- }
236
- function checkInteractionProgress(currentInteractions) {
237
- if (totalInteractions <= 0 || progressMilestones.length === 0) return;
238
- const currentPercent = currentInteractions / totalInteractions * 100;
239
- for (const milestone of progressMilestones) {
240
- if (!milestone.triggered && currentPercent >= milestone.percent) {
241
- milestone.triggered = true;
242
- milestone.callback();
243
- }
244
- }
245
- }
246
- function _onInit(adNetwork) {
247
- initProgressMilestones(adNetwork);
248
- const network = getCurrentAdNetwork(adNetwork);
249
- if (!network) return;
250
- if (network === "bigabid") {
251
- trackBigabidEvent("mraid_viewable");
252
- }
253
- if (network === "inmobi") {
254
- trackInMobiEvent("Ad_Load_Start");
255
- }
256
- if (network === "applovin") {
257
- trackApplovinEvent("LOADING");
258
- }
259
- }
260
- function _onStart(adNetwork) {
261
- const network = getCurrentAdNetwork(adNetwork);
262
- if (!network) return;
263
- if (network === "bigabid") {
264
- trackBigabidEvent("game_viewable");
265
- }
266
- if (network === "inmobi") {
267
- trackInMobiEvent("Ad_Viewable");
268
- startInMobiDurationTracking();
269
- }
270
- if (network === "applovin") {
271
- trackApplovinEvent("LOADED");
272
- }
273
- }
274
- function _onInteractive(adNetwork) {
275
- const network = getCurrentAdNetwork(adNetwork);
276
- if (!network) return;
277
- if (network === "applovin") {
278
- trackApplovinEvent("DISPLAYED");
279
- }
280
- }
281
- function _onInteraction(adNetwork) {
282
- const network = getCurrentAdNetwork(adNetwork);
283
- if (!network) return;
284
- if (network === "bigabid") {
285
- trackBigabidEvent("engagement");
286
- }
287
- if (network === "inmobi") {
288
- trackInMobiEvent("First_Engagement");
289
- }
290
- if (network === "applovin") {
291
- trackApplovinEvent("CHALLENGE_STARTED");
292
- }
293
- }
294
- function _onSuccess(successCount) {
295
- checkInteractionProgress(successCount);
296
- }
297
- function _onFinish(adNetwork) {
298
- const network = getCurrentAdNetwork(adNetwork);
299
- if (!network) return;
300
- if (network === "bigabid") {
301
- trackBigabidComplete();
302
- }
303
- if (network === "inmobi") {
304
- trackInMobiEvent("Gameplay_Complete");
305
- clearInMobiDurationTracking();
306
- }
307
- if (network === "applovin") {
308
- trackApplovinEvent("ENDCARD_SHOWN");
309
- }
310
- }
311
- function _onInstall(adNetwork) {
312
- const network = getCurrentAdNetwork(adNetwork);
313
- if (!network) return;
314
- if (network === "bigabid") {
315
- trackBigabidEvent("click");
316
- }
317
- if (network === "inmobi") {
318
- trackInMobiEvent("DSP_Click");
319
- clearInMobiDurationTracking();
320
- }
321
- if (network === "applovin") {
322
- trackApplovinEvent("CTA_CLICKED");
323
- }
324
- }
325
- function _onRetry(adNetwork) {
326
- const network = getCurrentAdNetwork(adNetwork);
327
- if (!network) return;
328
- if (network === "applovin") {
329
- trackApplovinEvent("CHALLENGE_RETRY");
330
- }
331
- }
332
- function _trackChallengeSuccess(adNetwork) {
333
- const network = getCurrentAdNetwork(adNetwork);
334
- if (!network) return;
335
- if (network === "applovin") {
336
- trackApplovinEvent("CHALLENGE_SOLVED");
337
- }
338
- if (network === "bigabid") {
339
- trackBigabidComplete();
340
- }
341
- if (network === "inmobi") {
342
- trackInMobiEvent("Gameplay_Complete");
343
- }
344
- }
345
- function _trackChallengeFailed(adNetwork) {
346
- const network = getCurrentAdNetwork(adNetwork);
347
- if (!network) return;
348
- if (network === "applovin") {
349
- trackApplovinEvent("CHALLENGE_FAILED");
350
- }
351
- }
352
- var tracking = {
353
- /**
354
- * SDK 初始化开始
355
- * @param adNetwork - 可选的广告渠道名称
356
- */
357
- onInit: _onInit,
358
- /**
359
- * 游戏资源加载完成
360
- * @param adNetwork - 可选的广告渠道名称
361
- */
362
- onStart: _onStart,
363
- /**
364
- * 主场景就绪,用户可交互
365
- * @param adNetwork - 可选的广告渠道名称
366
- */
367
- onInteractive: _onInteractive,
368
- /**
369
- * 首次交互
370
- * @param adNetwork - 可选的广告渠道名称
371
- */
372
- onInteraction: _onInteraction,
373
- /**
374
- * 成功计数(用于进度百分比追踪)
375
- * @param successCount - 当前成功次数
376
- */
377
- onSuccess: _onSuccess,
378
- /**
379
- * 游戏结束
380
- * @param adNetwork - 可选的广告渠道名称
381
- */
382
- onFinish: _onFinish,
383
- /**
384
- * 点击安装
385
- * @param adNetwork - 可选的广告渠道名称
386
- */
387
- onInstall: _onInstall,
388
- /**
389
- * 重试游戏
390
- * @param adNetwork - 可选的广告渠道名称
391
- */
392
- onRetry: _onRetry,
393
- /**
394
- * 设置交互总数(用于进度百分比计算)
395
- * @param total - 交互总数
396
- */
397
- setTotalInteractions,
398
- /**
399
- * 检查交互进度
400
- * @param currentInteractions - 当前交互次数
401
- */
402
- checkInteractionProgress,
403
- /**
404
- * 触发游戏成功事件
405
- * @param adNetwork - 可选的广告渠道名称
406
- */
407
- trackChallengeSuccess: _trackChallengeSuccess,
408
- /**
409
- * 触发游戏失败事件
410
- * @param adNetwork - 可选的广告渠道名称
411
- */
412
- trackChallengeFailed: _trackChallengeFailed
413
- };
414
-
415
160
  // src/tracking-init.ts
161
+ import { tracking } from "@playcraft/ads-tracking";
416
162
  function initTrackingProtocols() {
417
163
  const supportedNetworks = ["bigabid", "inmobi", "applovin"];
418
164
  if (!supportedNetworks.includes(AD_NETWORK)) {
419
165
  return;
420
166
  }
421
- sdk.once("init", tracking.onInit);
422
- sdk.once("start", tracking.onStart);
423
- sdk.once("interactive", tracking.onInteractive);
424
- sdk.once("interaction", tracking.onInteraction);
425
- sdk.on("success", tracking.onSuccess);
426
- sdk.once("finish", tracking.onFinish);
427
- sdk.on("install", tracking.onInstall);
428
- sdk.once("retry", tracking.onRetry);
167
+ sdk.once("playcraftInit", tracking.onPlaycraftTrackingInit);
168
+ sdk.once("playcraftStart", tracking.onPlaycraftTrackingLoading);
169
+ sdk.once("playcraftInteractive", tracking.onPlaycraftTrackingLoaded);
170
+ sdk.on("playcraftChallengeStart", tracking.onPlaycraftChallengeStart);
171
+ sdk.on("playcraftChallengeProgress", tracking.onPlaycraftChallengeProgress);
172
+ sdk.once("playcraftFinish", tracking.onPlaycraftChallengeFinish);
173
+ sdk.on("playcraftInstall", tracking.onPlaycraftInstall);
174
+ sdk.once("playcraftRetry", tracking.onPlaycraftRetry);
175
+ sdk.on("playcraftChallengeSuccess", tracking.onPlaycraftChallengeSuccess);
176
+ sdk.on("playcraftChallengeFailed", tracking.onPlaycraftChallengeFailed);
429
177
  }
430
178
 
431
179
  // src/assets/images.ts
@@ -693,6 +441,73 @@ function removeWechatGuide() {
693
441
  }
694
442
  }
695
443
 
444
+ // src/theme-config.ts
445
+ function extractDefaultsFromSchema(schema) {
446
+ if (!schema || typeof schema !== "object") return void 0;
447
+ if (schema.type === "object" && schema.properties) {
448
+ const result = {};
449
+ for (const [key, propSchema] of Object.entries(schema.properties)) {
450
+ const val = extractDefaultsFromSchema(propSchema);
451
+ if (val !== void 0) {
452
+ result[key] = val;
453
+ }
454
+ }
455
+ return Object.keys(result).length > 0 ? result : void 0;
456
+ }
457
+ if ("default" in schema) {
458
+ return schema.default;
459
+ }
460
+ return void 0;
461
+ }
462
+ function resolveImagePaths(config, assetRecordByPath) {
463
+ if (!assetRecordByPath || !config || typeof config !== "object") return;
464
+ for (const key of Object.keys(config)) {
465
+ const value = config[key];
466
+ if (typeof value === "string") {
467
+ if (assetRecordByPath[value]) {
468
+ config[key] = assetRecordByPath[value];
469
+ }
470
+ } else if (value !== null && typeof value === "object" && !Array.isArray(value)) {
471
+ resolveImagePaths(value, assetRecordByPath);
472
+ }
473
+ }
474
+ }
475
+ var _cachedConfig = null;
476
+ function deepMerge(target, source) {
477
+ for (const key of Object.keys(source)) {
478
+ const srcVal = source[key];
479
+ const tgtVal = target[key];
480
+ if (srcVal !== null && typeof srcVal === "object" && !Array.isArray(srcVal) && tgtVal !== null && typeof tgtVal === "object" && !Array.isArray(tgtVal)) {
481
+ deepMerge(tgtVal, srcVal);
482
+ } else if (srcVal !== void 0) {
483
+ target[key] = srcVal;
484
+ }
485
+ }
486
+ return target;
487
+ }
488
+ function setConfig(configList, config) {
489
+ const { assetRecordByPath } = config;
490
+ const resolvedConfigs = configList.map((item) => {
491
+ var _a;
492
+ if (!item) return {};
493
+ return item.$schema ? (_a = extractDefaultsFromSchema(item)) != null ? _a : {} : item;
494
+ });
495
+ const [first, ...rest] = resolvedConfigs;
496
+ const mergedConfig = JSON.parse(JSON.stringify(first));
497
+ for (const data of rest) {
498
+ deepMerge(mergedConfig, data);
499
+ }
500
+ resolveImagePaths(mergedConfig, assetRecordByPath);
501
+ _cachedConfig = mergedConfig;
502
+ }
503
+ function getConfig() {
504
+ if (!_cachedConfig) {
505
+ console.warn("[PlayableSDK] Theme config not initialized. Call setConfig() first.");
506
+ return {};
507
+ }
508
+ return _cachedConfig;
509
+ }
510
+
696
511
  // src/core.ts
697
512
  var destinationUrl = "";
698
513
  var isSDKInitialized = false;
@@ -704,16 +519,16 @@ var initCallback = () => {
704
519
  };
705
520
  function bootAd() {
706
521
  if (sdk.isReady) return;
707
- emitEvent("init");
522
+ emitEvent("playcraftInit");
708
523
  document.body.oncontextmenu = function() {
709
524
  return false;
710
525
  };
711
526
  initCallback(sdk.maxWidth, sdk.maxHeight);
712
- emitEvent("ready");
527
+ emitEvent("playcraftReady");
713
528
  sdk.isReady = true;
714
529
  }
715
530
  function fireVolumeChange(value) {
716
- emitEvent("volume", value);
531
+ emitEvent("playcraftVolume", value);
717
532
  }
718
533
  function changeVolume(value) {
719
534
  sdk.volume = value;
@@ -726,13 +541,13 @@ function handleVolumeChange(value) {
726
541
  function handlePause() {
727
542
  changeVolume(0);
728
543
  sdk.isPaused = true;
729
- emitEvent("pause");
544
+ emitEvent("playcraftPause");
730
545
  }
731
546
  function handleResume() {
732
547
  if (isForcePaused) return;
733
548
  changeVolume(actualVolume);
734
549
  sdk.isPaused = false;
735
- emitEvent("resume");
550
+ emitEvent("playcraftResume");
736
551
  }
737
552
  function fireResizeEvent(width, height) {
738
553
  handleResize(width, height);
@@ -915,7 +730,7 @@ function startDefaultProtocol() {
915
730
  const tapjoyApi = {
916
731
  skipAd: function() {
917
732
  try {
918
- sdk.finish();
733
+ sdk.playcraftFinish();
919
734
  } catch (e) {
920
735
  console.warn("Could not skip ad! | " + e);
921
736
  }
@@ -934,7 +749,7 @@ function handleResize(width, height) {
934
749
  sdk.maxWidth = Math.floor(width || window.innerWidth);
935
750
  sdk.maxHeight = Math.floor(height || window.innerHeight);
936
751
  sdk.isLandscape = sdk.maxWidth > sdk.maxHeight;
937
- emitEvent("resize", sdk.maxWidth, sdk.maxHeight);
752
+ emitEvent("playcraftResize", sdk.maxWidth, sdk.maxHeight);
938
753
  }
939
754
  var isListeningToTouchEvents = false;
940
755
  var isTouchEventRegistered = false;
@@ -944,7 +759,7 @@ function onUserInteraction(event) {
944
759
  }
945
760
  if (isListeningToTouchEvents && event instanceof MouseEvent) return;
946
761
  sdk.interactions += 1;
947
- emitEvent("interaction", sdk.interactions);
762
+ emitEvent("playcraftInteraction", sdk.interactions);
948
763
  }
949
764
  function registerTouchHandlers() {
950
765
  if (!isTouchEventRegistered) {
@@ -1028,35 +843,21 @@ var _sdk = class _sdk {
1028
843
  * This must be called as earlier as possible.
1029
844
  *
1030
845
  * @param callback Optional function called when ad container is ready
1031
- * @param options Optional configuration options
1032
- * @param options.totalSuccessCount Total number of successful actions expected for progress tracking.
1033
- * When set, the SDK will track success progress as a percentage and trigger
1034
- * channel-specific milestone events (e.g., AppLovin: CHALLENGE_PASS_25/50/75, CHALLENGE_SOLVED).
1035
- * Different channels monitor different percentage thresholds independently.
1036
- * Set to 0 or omit to disable progress tracking.
1037
846
  * @example
1038
847
  * // Basic initialization
1039
- * sdk.init();
848
+ * sdk.playcraftInit();
1040
849
  *
1041
850
  * // Initialization with callback
1042
- * sdk.init((width, height) => {
851
+ * sdk.playcraftInit((width, height) => {
1043
852
  * new App(width, height)
1044
853
  * });
1045
854
  *
1046
- * // Initialization with success count progress tracking
1047
- * sdk.init((width, height) => {
1048
- * new App(width, height)
1049
- * }, { totalSuccessCount: 20 });
1050
- *
1051
- * @fires loading When SDK initialization starts
1052
- * @fires loaded When game instance is created and ready to load resources
855
+ * @fires playcraftInit When SDK initialization starts
856
+ * @fires playcraftReady When game instance is created and ready to load resources
1053
857
  */
1054
- static init(callback, options) {
858
+ static playcraftInit(callback) {
1055
859
  if (isSDKInitialized) return;
1056
860
  if (callback) initCallback = callback;
1057
- if ((options == null ? void 0 : options.totalSuccessCount) && options.totalSuccessCount > 0) {
1058
- tracking.setTotalInteractions(options.totalSuccessCount);
1059
- }
1060
861
  initTrackingProtocols();
1061
862
  document.readyState === "loading" ? window.addEventListener("DOMContentLoaded", initSDK) : initSDK();
1062
863
  isSDKInitialized = true;
@@ -1066,25 +867,24 @@ var _sdk = class _sdk {
1066
867
  * Should be called after all resources are loaded and first frame is rendered.
1067
868
  *
1068
869
  * @example
1069
- * // Call just after all resources are preloaded and first frame is rendered
1070
- * sdk.start();
870
+ * sdk.playcraftStart();
1071
871
  *
1072
- * @fires start When the playable ad starts
1073
- * @fires resize When the ad container is initially sized
872
+ * @fires playcraftStart When the playable ad starts
873
+ * @fires playcraftResize When the ad container is initially sized
1074
874
  */
1075
- static start() {
875
+ static playcraftStart() {
1076
876
  if (_sdk.isStarted) return;
1077
877
  _sdk.isStarted = true;
1078
- emitEvent("start");
878
+ emitEvent("playcraftStart");
1079
879
  registerTouchHandlers();
1080
880
  if ("mintegral" === AD_NETWORK && isMintegral()) {
1081
- _sdk.resize();
881
+ _sdk.playcraftResize();
1082
882
  handlePause();
1083
883
  window.gameReady && window.gameReady();
1084
884
  } else if ("bigoads" === AD_NETWORK && isBigoAds()) {
1085
885
  window.BGY_MRAID && window.BGY_MRAID.gameReady && window.BGY_MRAID.gameReady();
1086
886
  fireVolumeChange(_sdk.volume);
1087
- _sdk.resize();
887
+ _sdk.playcraftResize();
1088
888
  } else {
1089
889
  if ("tapjoy" === AD_NETWORK && isTapjoy()) {
1090
890
  window.TJ_API.setPlayableBuild({
@@ -1093,7 +893,7 @@ var _sdk = class _sdk {
1093
893
  });
1094
894
  }
1095
895
  fireVolumeChange(_sdk.volume);
1096
- _sdk.resize();
896
+ _sdk.playcraftResize();
1097
897
  }
1098
898
  }
1099
899
  /**
@@ -1101,28 +901,39 @@ var _sdk = class _sdk {
1101
901
  * Should be called at the end of your main game scene's create() method.
1102
902
  *
1103
903
  * @example
1104
- * // In Phaser MainScene.create()
1105
904
  * create() {
1106
905
  * // ... all initialization code ...
1107
- * sdk.interactive();
906
+ * sdk.playcraftInteractive();
907
+ * }
908
+ *
909
+ * @fires playcraftInteractive When the main scene is ready for user interaction
910
+ */
911
+ static playcraftInteractive() {
912
+ emitEvent("playcraftInteractive");
913
+ }
914
+ /**
915
+ * Marks the challenge as started.
916
+ * Should be called by business logic when the user actually starts playing.
917
+ *
918
+ * @example
919
+ * onFirstClick() {
920
+ * sdk.playcraftChallengeStart();
1108
921
  * }
1109
922
  *
1110
- * @fires interactive When the main scene is ready for user interaction
923
+ * @fires playcraftChallengeStart When the challenge starts
1111
924
  */
1112
- static interactive() {
1113
- emitEvent("interactive");
925
+ static playcraftChallengeStart() {
926
+ emitEvent("playcraftChallengeStart");
1114
927
  }
1115
928
  /**
1116
929
  * Marks the playable ad as finished.
1117
- * This triggers network-specific completion handlers.
1118
930
  *
1119
931
  * @example
1120
- * // Call when game/experience is complete
1121
- * sdk.finish();
932
+ * sdk.playcraftFinish();
1122
933
  *
1123
- * @fires finish When the playable ad is marked as finished
934
+ * @fires playcraftFinish When the playable ad is marked as finished
1124
935
  */
1125
- static finish() {
936
+ static playcraftFinish() {
1126
937
  _sdk.isFinished = true;
1127
938
  if ("tapjoy" === AD_NETWORK && isTapjoy()) {
1128
939
  finishTapjoy();
@@ -1142,38 +953,34 @@ var _sdk = class _sdk {
1142
953
  console.warn("Could not call mraid.close():", e);
1143
954
  }
1144
955
  }
1145
- emitEvent("finish");
956
+ emitEvent("playcraftFinish");
1146
957
  }
1147
958
  /**
1148
959
  * Triggers a retry/restart of the playable ad.
1149
- * Behavior varies by ad network.
1150
960
  *
1151
961
  * @example
1152
- * // Allow user to try again
1153
- * retryButton.onclick = () => sdk.retry();
962
+ * retryButton.onclick = () => sdk.playcraftRetry();
1154
963
  *
1155
- * @fires retry When a retry is triggered
964
+ * @fires playcraftRetry When a retry is triggered
1156
965
  */
1157
- static retry() {
966
+ static playcraftRetry() {
1158
967
  if ("mintegral" === AD_NETWORK && isMintegral()) {
1159
968
  } else if ("nucleo" === AD_PROTOCOL && isNucleo()) {
1160
969
  NUC.trigger.tryAgain();
1161
970
  }
1162
- emitEvent("retry");
971
+ emitEvent("playcraftRetry");
1163
972
  }
1164
973
  /**
1165
974
  * Triggers the install/download action for the advertised app.
1166
- * Handles different store opening methods across ad networks.
1167
975
  *
1168
976
  * @example
1169
- * // Call when user wants to install
1170
- * installButton.onclick = () => sdk.install();
977
+ * installButton.onclick = () => sdk.playcraftInstall();
1171
978
  *
1172
- * @fires finish If the ad hasn't been marked as finished
1173
- * @fires install When the install action is triggered
979
+ * @fires playcraftFinish If the ad hasn't been marked as finished
980
+ * @fires playcraftInstall When the install action is triggered
1174
981
  */
1175
- static install(params) {
1176
- console.log("[SDK] install() called, interactions:", _sdk.interactions, "isFinished:", _sdk.isFinished, "isInstallClicked:", isInstallClicked);
982
+ static playcraftInstall(params) {
983
+ console.log("[SDK] playcraftInstall() called, interactions:", _sdk.interactions, "isFinished:", _sdk.isFinished, "isInstallClicked:", isInstallClicked);
1177
984
  if (_sdk.interactions < 1 && isDisableFirstClickToOpenApp()) {
1178
985
  console.log("[SDK] \u9996\u6B21\u70B9\u51FB\u4FDD\u62A4\uFF0C\u76F4\u63A5\u8FD4\u56DE");
1179
986
  return;
@@ -1183,23 +990,23 @@ var _sdk = class _sdk {
1183
990
  return;
1184
991
  }
1185
992
  const timeout = setTimeout(function() {
1186
- _sdk.install();
993
+ _sdk.playcraftInstall();
1187
994
  clearTimeout(timeout);
1188
995
  }, params.timeout || 3e3);
1189
996
  return;
1190
997
  }
1191
998
  if (!_sdk.isFinished) {
1192
- console.log("[SDK] \u9996\u6B21\u6267\u884C install\uFF0C\u89E6\u53D1 finish \u4E8B\u4EF6");
999
+ console.log("[SDK] \u9996\u6B21\u6267\u884C playcraftInstall\uFF0C\u89E6\u53D1 playcraftFinish \u4E8B\u4EF6");
1193
1000
  _sdk.isFinished = true;
1194
1001
  let timeout = 0;
1195
1002
  if ("tapjoy" === AD_NETWORK && isTapjoy()) {
1196
1003
  finishTapjoy();
1197
1004
  timeout = 300;
1198
1005
  }
1199
- emitEvent("finish");
1006
+ emitEvent("playcraftFinish");
1200
1007
  setTimeout(function() {
1201
- console.log("[SDK] \u5F02\u6B65\u9012\u5F52\u8C03\u7528 install()");
1202
- _sdk.install();
1008
+ console.log("[SDK] \u5F02\u6B65\u9012\u5F52\u8C03\u7528 playcraftInstall()");
1009
+ _sdk.playcraftInstall();
1203
1010
  }, timeout);
1204
1011
  return;
1205
1012
  }
@@ -1212,7 +1019,7 @@ var _sdk = class _sdk {
1212
1019
  isInstallClicked = false;
1213
1020
  console.log("[SDK] \u9632\u6296\u89E3\u9501");
1214
1021
  }, 500);
1215
- emitEvent("install");
1022
+ emitEvent("playcraftInstall");
1216
1023
  console.log("Ad_Protocal: ", AD_PROTOCOL);
1217
1024
  if ("mraid" === AD_PROTOCOL && isMraid()) {
1218
1025
  try {
@@ -1276,39 +1083,30 @@ var _sdk = class _sdk {
1276
1083
  }
1277
1084
  /**
1278
1085
  * Trigger force resize event
1279
- * Useful when container size changes need to be manually propagated.
1280
1086
  *
1281
1087
  * @example
1282
- * sdk.resize();
1088
+ * sdk.playcraftResize();
1283
1089
  *
1284
- * @fires resize With current maxWidth and maxHeight
1090
+ * @fires playcraftResize With current maxWidth and maxHeight
1285
1091
  */
1286
- static resize() {
1092
+ static playcraftResize() {
1287
1093
  handleResize(_sdk.maxWidth, _sdk.maxHeight);
1288
1094
  }
1289
1095
  /**
1290
- * Records successful game actions (e.g., successful match, level clear).
1291
- * This should be called by game logic when a meaningful success occurs.
1292
- * This count is used for progress tracking (e.g., AppLovin milestone events).
1096
+ * Records playable ad challenge progress (0-100).
1097
+ * Triggers channel-specific milestone events based on the progress value.
1098
+ * Milestones are not re-triggered once fired.
1099
+ *
1100
+ * @param percent Progress percentage (0-100)
1293
1101
  *
1294
- * @param count Optional success count to add (default: 1)
1295
- *
1296
1102
  * @example
1297
- * // Record single success when match completes
1298
- * onMatchSuccess() {
1299
- * sdk.recordSuccessCount();
1300
- * }
1301
- *
1302
- * // Record multiple successes at once
1303
- * onComboMatch(comboCount) {
1304
- * sdk.recordSuccessCount(comboCount);
1305
- * }
1103
+ * // Report 50% progress
1104
+ * sdk.recordPlaycraftChallengeProgress(50);
1306
1105
  *
1307
- * @fires success With updated success count (triggers progress tracking)
1106
+ * @fires playcraftChallengeProgress With the progress percentage value
1308
1107
  */
1309
- static recordSuccessCount(count = 1) {
1310
- _sdk.successCount += count;
1311
- emitEvent("success", _sdk.successCount);
1108
+ static recordPlaycraftChallengeProgress(percent) {
1109
+ emitEvent("playcraftChallengeProgress", percent);
1312
1110
  }
1313
1111
  /**
1314
1112
  * Records a game success/completion event.
@@ -1318,13 +1116,12 @@ var _sdk = class _sdk {
1318
1116
  * - InMobi: Gameplay_Complete
1319
1117
  *
1320
1118
  * @example
1321
- * // When player completes the level
1322
1119
  * onLevelComplete() {
1323
- * sdk.recordSuccess();
1120
+ * sdk.playcraftRecordSuccess();
1324
1121
  * }
1325
1122
  */
1326
- static recordSuccess() {
1327
- tracking.trackChallengeSuccess();
1123
+ static playcraftRecordSuccess() {
1124
+ emitEvent("playcraftChallengeSuccess");
1328
1125
  }
1329
1126
  /**
1330
1127
  * Records a game failure event.
@@ -1332,24 +1129,22 @@ var _sdk = class _sdk {
1332
1129
  * - AppLovin: CHALLENGE_FAILED
1333
1130
  *
1334
1131
  * @example
1335
- * // When player fails the level
1336
1132
  * onLevelFailed() {
1337
- * sdk.recordFailed();
1133
+ * sdk.playcraftRecordFailed();
1338
1134
  * }
1339
1135
  */
1340
- static recordFailed() {
1341
- tracking.trackChallengeFailed();
1136
+ static playcraftRecordFailed() {
1137
+ emitEvent("playcraftChallengeFailed");
1342
1138
  }
1343
1139
  /**
1344
1140
  * Forces the playable ad into a paused state.
1345
1141
  *
1346
1142
  * @example
1347
- * // Pause the experience
1348
- * pauseButton.onclick = () => sdk.pause();
1143
+ * pauseButton.onclick = () => sdk.playcraftPause();
1349
1144
  *
1350
- * @fires pause When the ad enters paused state
1145
+ * @fires playcraftPause When the ad enters paused state
1351
1146
  */
1352
- static pause() {
1147
+ static playcraftPause() {
1353
1148
  if (!isForcePaused) {
1354
1149
  isForcePaused = true;
1355
1150
  handlePause();
@@ -1357,15 +1152,13 @@ var _sdk = class _sdk {
1357
1152
  }
1358
1153
  /**
1359
1154
  * Resumes the playable ad from a forced pause state.
1360
- * Only works if the ad was paused via sdk.pause().
1361
1155
  *
1362
1156
  * @example
1363
- * // Resume from pause
1364
- * resumeButton.onclick = () => sdk.resume();
1157
+ * resumeButton.onclick = () => sdk.playcraftResume();
1365
1158
  *
1366
- * @fires resume When the ad resumes from pause
1159
+ * @fires playcraftResume When the ad resumes from pause
1367
1160
  */
1368
- static resume() {
1161
+ static playcraftResume() {
1369
1162
  if (isForcePaused) {
1370
1163
  isForcePaused = false;
1371
1164
  handleResume();
@@ -1379,15 +1172,9 @@ var _sdk = class _sdk {
1379
1172
  * @param context Optional 'this' context for the callback
1380
1173
  *
1381
1174
  * @example
1382
- * // Listen for user interactions
1383
- * sdk.on('interaction', (count) => {
1175
+ * sdk.on('playcraftInteraction', (count) => {
1384
1176
  * console.log(`User interaction #${count}`);
1385
1177
  * });
1386
- *
1387
- * // Listen for resize with context
1388
- * sdk.on('resize', function(width, height) {
1389
- * this.updateLayout(width, height);
1390
- * }, gameInstance);
1391
1178
  */
1392
1179
  static on(event, fn, context) {
1393
1180
  onEvent(event, fn, context);
@@ -1400,8 +1187,7 @@ var _sdk = class _sdk {
1400
1187
  * @param context Optional 'this' context for the callback
1401
1188
  *
1402
1189
  * @example
1403
- * // Listen for first interaction only
1404
- * sdk.once('interaction', () => {
1190
+ * sdk.once('playcraftInteraction', () => {
1405
1191
  * console.log('First user interaction occurred!');
1406
1192
  * });
1407
1193
  */
@@ -1412,22 +1198,16 @@ var _sdk = class _sdk {
1412
1198
  * Removes an event listener.
1413
1199
  *
1414
1200
  * @param event Name of the event to stop listening for
1415
- * @param fn Optional callback function to remove (if not provided, removes all listeners for the event)
1201
+ * @param fn Optional callback function to remove
1416
1202
  * @param context Optional 'this' context to match when removing
1417
1203
  *
1418
1204
  * @example
1419
- * // Remove specific listener
1420
- * const handler = () => console.log('Interaction');
1421
- * sdk.off('interaction', handler);
1422
- *
1423
- * // Remove all listeners for an event
1424
- * sdk.off('interaction');
1205
+ * sdk.off('playcraftInteraction', handler);
1425
1206
  */
1426
1207
  static off(event, fn, context) {
1427
1208
  offEvent(event, fn, context);
1428
1209
  }
1429
1210
  /**
1430
- *
1431
1211
  * @returns 当前渠道
1432
1212
  */
1433
1213
  static getCurChannel() {
@@ -1439,9 +1219,43 @@ var _sdk = class _sdk {
1439
1219
  static isGoogle() {
1440
1220
  return _sdk.getCurChannel() === "google";
1441
1221
  }
1222
+ /**
1223
+ * 设置主题配置,支持传入多份 JSON5 配置。
1224
+ * 每一份配置都可以是 JSON Schema(带 $schema 字段),会自动提取其中的 default 值。
1225
+ * 所有配置按顺序依次深度合并,后面的优先级更高。
1226
+ *
1227
+ * @param configList - 配置数组,每一项可以是:
1228
+ * - JSON Schema(带 $schema 字段):自动提取 default 值后参与合并
1229
+ * - 普通配置对象:直接参与合并
1230
+ * @param config - 额外配置项
1231
+ * - config.assetRecordByPath: 相对路径到已解析 URL 的映射
1232
+ *
1233
+ * @example
1234
+ * sdk.setConfig(
1235
+ * [schemaA, schemaB, themeData],
1236
+ * { assetRecordByPath: imageAssets }
1237
+ * );
1238
+ */
1239
+ static setConfig(configList, config) {
1240
+ setConfig(configList, config);
1241
+ }
1242
+ /**
1243
+ * 获取合并后的主题配置。
1244
+ * 返回 schema 默认值与用户主题数据深度合并后的结果。
1245
+ * 必须先调用 sdk.setConfig() 才能使用此方法。
1246
+ *
1247
+ * @returns 合并后的主题配置对象
1248
+ *
1249
+ * @example
1250
+ * const config = sdk.getConfig();
1251
+ * console.log(config.primaryColor); // '#ff0000'
1252
+ */
1253
+ static getConfig() {
1254
+ return getConfig();
1255
+ }
1442
1256
  };
1443
1257
  /** Current version of the SDK */
1444
- _sdk.version = "1.0.12";
1258
+ _sdk.version = "1.0.13-beta.1";
1445
1259
  /** Current maximum width of the playable ad container in pixels */
1446
1260
  _sdk.maxWidth = Math.floor(window.innerWidth);
1447
1261
  /** Current maximum height of the playable ad container in pixels */
@@ -1460,10 +1274,6 @@ _sdk.isFinished = false;
1460
1274
  _sdk.volume = actualVolume;
1461
1275
  /** Number of user interactions with the playable ad (auto-incremented on each touch/click) */
1462
1276
  _sdk.interactions = 0;
1463
- /** Number of successful game actions (e.g., successful matches, level clears).
1464
- * Controlled by calling sdk.recordSuccessCount(), NOT auto-incremented.
1465
- */
1466
- _sdk.successCount = 0;
1467
1277
  var sdk = _sdk;
1468
1278
  window["console"].log(
1469
1279
  `%c @playcraft/adsdk %c v${sdk.version} `,
@@ -1476,6 +1286,5 @@ export {
1476
1286
  hideWechatGuide,
1477
1287
  removeWechatGuide,
1478
1288
  sdk,
1479
- showWechatGuide,
1480
- tracking
1289
+ showWechatGuide
1481
1290
  };