@bountyboard/arcade-sdk 1.0.0 → 1.0.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/global.js CHANGED
@@ -42,6 +42,11 @@
42
42
  function cleanRewardedSize(value) {
43
43
  return value === "small" || value === "medium" || value === "large" ? value : "";
44
44
  }
45
+ function hasTransientUserActivation() {
46
+ if (typeof navigator === "undefined") return false;
47
+ const activation = navigator.userActivation;
48
+ return (activation == null ? void 0 : activation.isActive) === true;
49
+ }
45
50
  function safeCall(fn, arg) {
46
51
  if (typeof fn !== "function") return;
47
52
  try {
@@ -118,7 +123,7 @@
118
123
  function createBBArcade() {
119
124
  let adPlacementLoad = null;
120
125
  let adPreloadConfigured = false;
121
- let rewardedBreakActive = false;
126
+ let rewardedBreakActive = null;
122
127
  let rewardedBreakSequence = 0;
123
128
  function isLocalAdHost() {
124
129
  try {
@@ -529,6 +534,16 @@
529
534
  function show() {
530
535
  if (shown) return;
531
536
  shown = true;
537
+ if (!hasTransientUserActivation()) {
538
+ const activationError = Object.assign(
539
+ { status: "error", error: "direct_user_action_required" },
540
+ base
541
+ );
542
+ post("rewarded_ad", void 0, Object.assign({ event: "error" }, activationError));
543
+ safeCall(options.onError, activationError);
544
+ done(activationError);
545
+ return;
546
+ }
532
547
  post("rewarded_ad", void 0, Object.assign({ event: "started" }, base));
533
548
  try {
534
549
  showAdFn();
@@ -552,6 +567,7 @@
552
567
  base
553
568
  );
554
569
  post("rewarded_ad", void 0, Object.assign({ event: "error" }, beforeError));
570
+ if (shown) return;
555
571
  safeCall(options.onError, beforeError);
556
572
  done(beforeError);
557
573
  }
@@ -560,9 +576,9 @@
560
576
  adBreak({
561
577
  type: "reward",
562
578
  name: options.placement,
563
- size: options.size || void 0,
564
579
  beforeReward: startAd,
565
580
  adViewed: function() {
581
+ if (resolved) return;
566
582
  status = "viewed";
567
583
  const viewed = Object.assign({ status }, base);
568
584
  post("rewarded_ad", void 0, Object.assign({ event: "viewed" }, viewed));
@@ -570,6 +586,7 @@
570
586
  safeCall(options.onReward, viewed);
571
587
  },
572
588
  adDismissed: function() {
589
+ if (resolved) return;
573
590
  if (status !== "viewed") status = "dismissed";
574
591
  const dismissed = Object.assign({ status }, base);
575
592
  post("rewarded_ad", void 0, Object.assign({ event: "dismissed" }, dismissed));
@@ -577,6 +594,7 @@
577
594
  safeCall(options.onDismissed, dismissed);
578
595
  },
579
596
  adBreakDone: function(placementInfo) {
597
+ if (resolved) return;
580
598
  const result = rewardOffered || status !== "unavailable" ? { status } : { status: "unavailable", error: "no_rewarded_ad" };
581
599
  if (placementInfo && typeof placementInfo === "object") {
582
600
  result.breakStatus = cleanText(
@@ -610,6 +628,52 @@
610
628
  });
611
629
  });
612
630
  }
631
+ function prepareRewardedAd(rawOptions) {
632
+ const normalized = normalizeRewardedOptions(rawOptions);
633
+ const base = {
634
+ placement: normalized.placement,
635
+ reward: normalized.reward,
636
+ adBreakId: normalized.adBreakId
637
+ };
638
+ if (normalized.size) base.size = normalized.size;
639
+ let ready2 = false;
640
+ let finalPromise;
641
+ return new Promise(function(resolvePreparation) {
642
+ finalPromise = rewardedAd(
643
+ Object.assign({}, rawOptions, {
644
+ // Preserve the id used by the ready handle and every lifecycle event;
645
+ // rewardedAd normalizes again, but this explicit id keeps both stages
646
+ // tied to the same placement.
647
+ adBreakId: normalized.adBreakId,
648
+ beforeReward: function(showAd) {
649
+ if (ready2) return;
650
+ ready2 = true;
651
+ let shown = false;
652
+ const prepared = Object.assign(
653
+ { status: "ready" },
654
+ base,
655
+ {
656
+ show: function() {
657
+ if (!shown) {
658
+ shown = true;
659
+ if (hasTransientUserActivation()) {
660
+ safeCall(rawOptions && rawOptions.onStart);
661
+ }
662
+ showAd();
663
+ }
664
+ return finalPromise;
665
+ }
666
+ }
667
+ );
668
+ resolvePreparation(prepared);
669
+ }
670
+ })
671
+ );
672
+ finalPromise.then(function(result) {
673
+ if (!ready2) resolvePreparation(result);
674
+ });
675
+ });
676
+ }
613
677
  function preloadRewardedAds(rawOptions) {
614
678
  const options = normalizeRewardedOptions(rawOptions);
615
679
  if (!areRewardedAdsEnabled()) return Promise.resolve(false);
@@ -656,7 +720,7 @@
656
720
  reward: normalized.reward
657
721
  };
658
722
  if (normalized.size) base.size = normalized.size;
659
- if (rewardedBreakActive) {
723
+ if (rewardedBreakActive && rewardedBreakActive.state !== "ready") {
660
724
  post(
661
725
  "rewarded_ad",
662
726
  void 0,
@@ -667,24 +731,32 @@
667
731
  );
668
732
  return Promise.resolve(false);
669
733
  }
670
- rewardedBreakActive = true;
734
+ const activeBreak = { state: "loading" };
735
+ rewardedBreakActive = activeBreak;
671
736
  let startCalled = false;
737
+ const callerBeforeReward = rawOptions.beforeReward;
672
738
  return rewardedAd(
673
739
  Object.assign({}, rawOptions, {
674
740
  beforeReward: function(showAd) {
675
- if (startCalled) return;
676
- startCalled = true;
677
- safeCall(rawOptions.onStart);
678
- showAd();
741
+ if (rewardedBreakActive === activeBreak) activeBreak.state = "ready";
742
+ const showWithStart = function() {
743
+ if (startCalled || rewardedBreakActive !== activeBreak) return;
744
+ startCalled = true;
745
+ activeBreak.state = "showing";
746
+ if (hasTransientUserActivation()) safeCall(rawOptions.onStart);
747
+ showAd();
748
+ };
749
+ if (typeof callerBeforeReward === "function") callerBeforeReward(showWithStart);
750
+ else showWithStart();
679
751
  }
680
752
  })
681
753
  ).then(
682
754
  function(result) {
683
- rewardedBreakActive = false;
755
+ if (rewardedBreakActive === activeBreak) rewardedBreakActive = null;
684
756
  return Boolean(result && result.status === "viewed");
685
757
  },
686
758
  function() {
687
- rewardedBreakActive = false;
759
+ if (rewardedBreakActive === activeBreak) rewardedBreakActive = null;
688
760
  return false;
689
761
  }
690
762
  );
@@ -722,6 +794,8 @@
722
794
  },
723
795
  rewardedAd,
724
796
  showRewardedAd: rewardedAd,
797
+ prepareRewardedAd,
798
+ prepareRewardedBreak: prepareRewardedAd,
725
799
  rewardedBreak,
726
800
  save: function(blob) {
727
801
  return request("save", String(blob));
@@ -767,6 +841,13 @@
767
841
  reward: "reward",
768
842
  adBreakId: "bbad_inert"
769
843
  });
844
+ const prepareUnavailable = () => Promise.resolve({
845
+ status: "unavailable",
846
+ error: "ad_break_unavailable",
847
+ placement: "rewarded",
848
+ reward: "reward",
849
+ adBreakId: "bbad_inert"
850
+ });
770
851
  return {
771
852
  lockToHost: noop,
772
853
  init: () => Promise.resolve(),
@@ -783,6 +864,8 @@
783
864
  xrSessionEnd: noop,
784
865
  rewardedAd: unavailable,
785
866
  showRewardedAd: unavailable,
867
+ prepareRewardedAd: prepareUnavailable,
868
+ prepareRewardedBreak: prepareUnavailable,
786
869
  rewardedBreak: () => Promise.resolve(false),
787
870
  save: () => Promise.reject(sdkError2("unsupported")),
788
871
  load: () => Promise.reject(sdkError2("unsupported")),
package/dist/index.cjs CHANGED
@@ -68,6 +68,11 @@ function toBoolean(value) {
68
68
  function cleanRewardedSize(value) {
69
69
  return value === "small" || value === "medium" || value === "large" ? value : "";
70
70
  }
71
+ function hasTransientUserActivation() {
72
+ if (typeof navigator === "undefined") return false;
73
+ const activation = navigator.userActivation;
74
+ return (activation == null ? void 0 : activation.isActive) === true;
75
+ }
71
76
  function safeCall(fn, arg) {
72
77
  if (typeof fn !== "function") return;
73
78
  try {
@@ -144,7 +149,7 @@ function sanitizePlayer(value) {
144
149
  function createBBArcade() {
145
150
  let adPlacementLoad = null;
146
151
  let adPreloadConfigured = false;
147
- let rewardedBreakActive = false;
152
+ let rewardedBreakActive = null;
148
153
  let rewardedBreakSequence = 0;
149
154
  function isLocalAdHost() {
150
155
  try {
@@ -555,6 +560,16 @@ function createBBArcade() {
555
560
  function show() {
556
561
  if (shown) return;
557
562
  shown = true;
563
+ if (!hasTransientUserActivation()) {
564
+ const activationError = Object.assign(
565
+ { status: "error", error: "direct_user_action_required" },
566
+ base
567
+ );
568
+ post("rewarded_ad", void 0, Object.assign({ event: "error" }, activationError));
569
+ safeCall(options.onError, activationError);
570
+ done(activationError);
571
+ return;
572
+ }
558
573
  post("rewarded_ad", void 0, Object.assign({ event: "started" }, base));
559
574
  try {
560
575
  showAdFn();
@@ -578,6 +593,7 @@ function createBBArcade() {
578
593
  base
579
594
  );
580
595
  post("rewarded_ad", void 0, Object.assign({ event: "error" }, beforeError));
596
+ if (shown) return;
581
597
  safeCall(options.onError, beforeError);
582
598
  done(beforeError);
583
599
  }
@@ -586,9 +602,9 @@ function createBBArcade() {
586
602
  adBreak({
587
603
  type: "reward",
588
604
  name: options.placement,
589
- size: options.size || void 0,
590
605
  beforeReward: startAd,
591
606
  adViewed: function() {
607
+ if (resolved) return;
592
608
  status = "viewed";
593
609
  const viewed = Object.assign({ status }, base);
594
610
  post("rewarded_ad", void 0, Object.assign({ event: "viewed" }, viewed));
@@ -596,6 +612,7 @@ function createBBArcade() {
596
612
  safeCall(options.onReward, viewed);
597
613
  },
598
614
  adDismissed: function() {
615
+ if (resolved) return;
599
616
  if (status !== "viewed") status = "dismissed";
600
617
  const dismissed = Object.assign({ status }, base);
601
618
  post("rewarded_ad", void 0, Object.assign({ event: "dismissed" }, dismissed));
@@ -603,6 +620,7 @@ function createBBArcade() {
603
620
  safeCall(options.onDismissed, dismissed);
604
621
  },
605
622
  adBreakDone: function(placementInfo) {
623
+ if (resolved) return;
606
624
  const result = rewardOffered || status !== "unavailable" ? { status } : { status: "unavailable", error: "no_rewarded_ad" };
607
625
  if (placementInfo && typeof placementInfo === "object") {
608
626
  result.breakStatus = cleanText(
@@ -636,6 +654,52 @@ function createBBArcade() {
636
654
  });
637
655
  });
638
656
  }
657
+ function prepareRewardedAd(rawOptions) {
658
+ const normalized = normalizeRewardedOptions(rawOptions);
659
+ const base = {
660
+ placement: normalized.placement,
661
+ reward: normalized.reward,
662
+ adBreakId: normalized.adBreakId
663
+ };
664
+ if (normalized.size) base.size = normalized.size;
665
+ let ready2 = false;
666
+ let finalPromise;
667
+ return new Promise(function(resolvePreparation) {
668
+ finalPromise = rewardedAd(
669
+ Object.assign({}, rawOptions, {
670
+ // Preserve the id used by the ready handle and every lifecycle event;
671
+ // rewardedAd normalizes again, but this explicit id keeps both stages
672
+ // tied to the same placement.
673
+ adBreakId: normalized.adBreakId,
674
+ beforeReward: function(showAd) {
675
+ if (ready2) return;
676
+ ready2 = true;
677
+ let shown = false;
678
+ const prepared = Object.assign(
679
+ { status: "ready" },
680
+ base,
681
+ {
682
+ show: function() {
683
+ if (!shown) {
684
+ shown = true;
685
+ if (hasTransientUserActivation()) {
686
+ safeCall(rawOptions && rawOptions.onStart);
687
+ }
688
+ showAd();
689
+ }
690
+ return finalPromise;
691
+ }
692
+ }
693
+ );
694
+ resolvePreparation(prepared);
695
+ }
696
+ })
697
+ );
698
+ finalPromise.then(function(result) {
699
+ if (!ready2) resolvePreparation(result);
700
+ });
701
+ });
702
+ }
639
703
  function preloadRewardedAds(rawOptions) {
640
704
  const options = normalizeRewardedOptions(rawOptions);
641
705
  if (!areRewardedAdsEnabled()) return Promise.resolve(false);
@@ -682,7 +746,7 @@ function createBBArcade() {
682
746
  reward: normalized.reward
683
747
  };
684
748
  if (normalized.size) base.size = normalized.size;
685
- if (rewardedBreakActive) {
749
+ if (rewardedBreakActive && rewardedBreakActive.state !== "ready") {
686
750
  post(
687
751
  "rewarded_ad",
688
752
  void 0,
@@ -693,24 +757,32 @@ function createBBArcade() {
693
757
  );
694
758
  return Promise.resolve(false);
695
759
  }
696
- rewardedBreakActive = true;
760
+ const activeBreak = { state: "loading" };
761
+ rewardedBreakActive = activeBreak;
697
762
  let startCalled = false;
763
+ const callerBeforeReward = rawOptions.beforeReward;
698
764
  return rewardedAd(
699
765
  Object.assign({}, rawOptions, {
700
766
  beforeReward: function(showAd) {
701
- if (startCalled) return;
702
- startCalled = true;
703
- safeCall(rawOptions.onStart);
704
- showAd();
767
+ if (rewardedBreakActive === activeBreak) activeBreak.state = "ready";
768
+ const showWithStart = function() {
769
+ if (startCalled || rewardedBreakActive !== activeBreak) return;
770
+ startCalled = true;
771
+ activeBreak.state = "showing";
772
+ if (hasTransientUserActivation()) safeCall(rawOptions.onStart);
773
+ showAd();
774
+ };
775
+ if (typeof callerBeforeReward === "function") callerBeforeReward(showWithStart);
776
+ else showWithStart();
705
777
  }
706
778
  })
707
779
  ).then(
708
780
  function(result) {
709
- rewardedBreakActive = false;
781
+ if (rewardedBreakActive === activeBreak) rewardedBreakActive = null;
710
782
  return Boolean(result && result.status === "viewed");
711
783
  },
712
784
  function() {
713
- rewardedBreakActive = false;
785
+ if (rewardedBreakActive === activeBreak) rewardedBreakActive = null;
714
786
  return false;
715
787
  }
716
788
  );
@@ -748,6 +820,8 @@ function createBBArcade() {
748
820
  },
749
821
  rewardedAd,
750
822
  showRewardedAd: rewardedAd,
823
+ prepareRewardedAd,
824
+ prepareRewardedBreak: prepareRewardedAd,
751
825
  rewardedBreak,
752
826
  save: function(blob) {
753
827
  return request("save", String(blob));
@@ -793,6 +867,13 @@ function createInertBBArcade() {
793
867
  reward: "reward",
794
868
  adBreakId: "bbad_inert"
795
869
  });
870
+ const prepareUnavailable = () => Promise.resolve({
871
+ status: "unavailable",
872
+ error: "ad_break_unavailable",
873
+ placement: "rewarded",
874
+ reward: "reward",
875
+ adBreakId: "bbad_inert"
876
+ });
796
877
  return {
797
878
  lockToHost: noop,
798
879
  init: () => Promise.resolve(),
@@ -809,6 +890,8 @@ function createInertBBArcade() {
809
890
  xrSessionEnd: noop,
810
891
  rewardedAd: unavailable,
811
892
  showRewardedAd: unavailable,
893
+ prepareRewardedAd: prepareUnavailable,
894
+ prepareRewardedBreak: prepareUnavailable,
812
895
  rewardedBreak: () => Promise.resolve(false),
813
896
  save: () => Promise.reject(sdkError2("unsupported")),
814
897
  load: () => Promise.reject(sdkError2("unsupported")),