@mpgd/adapter-ait 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ad-config.d.ts +2 -1
- package/dist/ad-config.js +4 -1
- package/dist/host.d.ts +17 -2
- package/dist/host.js +201 -2
- package/dist/index.js +7 -0
- package/dist/local-mock.d.ts +16 -0
- package/dist/local-mock.js +8 -0
- package/package.json +4 -4
package/dist/ad-config.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
export type AitAdPlacementType = 'rewarded' | 'interstitial' | 'banner';
|
|
1
2
|
export interface AitAdBridgeConfig {
|
|
2
3
|
readonly adGroupIds: Readonly<Record<string, string>>;
|
|
3
|
-
readonly adPlacementTypes: Readonly<Record<string,
|
|
4
|
+
readonly adPlacementTypes: Readonly<Record<string, AitAdPlacementType>>;
|
|
4
5
|
}
|
|
5
6
|
export declare function extractAitAdBridgeConfig(input: unknown, sourceLabel?: string): AitAdBridgeConfig;
|
package/dist/ad-config.js
CHANGED
|
@@ -9,7 +9,7 @@ export function extractAitAdBridgeConfig(input, sourceLabel = 'ad placements') {
|
|
|
9
9
|
for (const [placementIndex, placement] of placements.entries()) {
|
|
10
10
|
if (!isRecord(placement)
|
|
11
11
|
|| typeof placement.id !== 'string'
|
|
12
|
-
|| (placement.type
|
|
12
|
+
|| !isAitAdPlacementType(placement.type)) {
|
|
13
13
|
throw new Error(`AIT ad placement entry at index ${placementIndex} is invalid: ${sourceLabel}`);
|
|
14
14
|
}
|
|
15
15
|
if (placementIds.has(placement.id)) {
|
|
@@ -28,6 +28,9 @@ export function extractAitAdBridgeConfig(input, sourceLabel = 'ad placements') {
|
|
|
28
28
|
}
|
|
29
29
|
return { adGroupIds, adPlacementTypes };
|
|
30
30
|
}
|
|
31
|
+
function isAitAdPlacementType(value) {
|
|
32
|
+
return value === 'rewarded' || value === 'interstitial' || value === 'banner';
|
|
33
|
+
}
|
|
31
34
|
function isRecord(value) {
|
|
32
35
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
33
36
|
}
|
package/dist/host.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { getTossShareLink, grantPromotionRewardForGame as grantPromotionReward, IAP, isMinVersionSupported, loadFullScreenAd, openGameCenterLeaderboard, requestNotificationAgreement, share, showFullScreenAd, Storage, submitGameCenterLeaderBoardScore } from '@apps-in-toss/web-framework';
|
|
1
|
+
import { getTossShareLink, grantPromotionRewardForGame as grantPromotionReward, IAP, isMinVersionSupported, loadFullScreenAd, openGameCenterLeaderboard, requestNotificationAgreement, share, showFullScreenAd, Storage, submitGameCenterLeaderBoardScore, TossAds } from '@apps-in-toss/web-framework';
|
|
2
2
|
import type { Entitlement, LogicalProductId, NotificationTopic, ShareResult } from '@mpgd/platform';
|
|
3
|
+
import type { AitAdPlacementType } from './ad-config.js';
|
|
3
4
|
import type { GamePlatformBridge } from './index.js';
|
|
4
5
|
export type AitIdentityProvider = () => Promise<unknown>;
|
|
5
6
|
/**
|
|
@@ -18,6 +19,10 @@ interface AitIapDependencies {
|
|
|
18
19
|
readonly getPendingOrders: AitNativeMethod<typeof IAP.getPendingOrders>;
|
|
19
20
|
readonly completeProductGrant: AitNativeMethod<typeof IAP.completeProductGrant>;
|
|
20
21
|
}
|
|
22
|
+
interface AitBannerDependencies {
|
|
23
|
+
readonly initialize: typeof TossAds.initialize;
|
|
24
|
+
readonly attachBanner: typeof TossAds.attachBanner;
|
|
25
|
+
}
|
|
21
26
|
export interface AitHostDependencies {
|
|
22
27
|
readonly identityProvider: AitIdentityProvider;
|
|
23
28
|
readonly storage: Pick<typeof Storage, 'getItem' | 'removeItem' | 'setItem'>;
|
|
@@ -28,6 +33,7 @@ export interface AitHostDependencies {
|
|
|
28
33
|
readonly isMinVersionSupported: typeof isMinVersionSupported;
|
|
29
34
|
readonly loadFullScreenAd: AitNativeMethod<typeof loadFullScreenAd>;
|
|
30
35
|
readonly showFullScreenAd: AitNativeMethod<typeof showFullScreenAd>;
|
|
36
|
+
readonly tossAds: AitBannerDependencies;
|
|
31
37
|
readonly openGameCenterLeaderboard: AitNativeMethod<typeof openGameCenterLeaderboard>;
|
|
32
38
|
readonly submitGameCenterLeaderBoardScore: AitNativeMethod<typeof submitGameCenterLeaderBoardScore>;
|
|
33
39
|
readonly iap: AitIapDependencies;
|
|
@@ -108,10 +114,15 @@ export type AitPromotionGrantAuthorization = {
|
|
|
108
114
|
* single-use game claim.
|
|
109
115
|
*/
|
|
110
116
|
export type AitPromotionGrantAuthorizer = (input: AitPromotionGrantAuthorizationInput) => Promise<AitPromotionGrantAuthorization>;
|
|
117
|
+
export interface AitBannerAppearance {
|
|
118
|
+
readonly theme?: 'auto' | 'light' | 'dark';
|
|
119
|
+
readonly tone?: 'blackAndWhite' | 'grey';
|
|
120
|
+
readonly variant?: 'card' | 'expanded';
|
|
121
|
+
}
|
|
111
122
|
export interface InstallAitHostBridgeOptions {
|
|
112
123
|
readonly appName?: string;
|
|
113
124
|
readonly adGroupIds?: Readonly<Record<string, string>>;
|
|
114
|
-
readonly adPlacementTypes?: Readonly<Record<string,
|
|
125
|
+
readonly adPlacementTypes?: Readonly<Record<string, AitAdPlacementType>>;
|
|
115
126
|
/** Logical campaign ids mapped to console-issued Apps in Toss promotion configuration. */
|
|
116
127
|
readonly promotionRewards?: Readonly<Record<string, AitPromotionRewardConfig>>;
|
|
117
128
|
readonly authorizePromotionGrant?: AitPromotionGrantAuthorizer;
|
|
@@ -134,6 +145,10 @@ export interface InstallAitHostBridgeOptions {
|
|
|
134
145
|
readonly adDisplayStartTimeoutMs?: number;
|
|
135
146
|
/** Last-resort cleanup when the native SDK omits its terminal display callback. */
|
|
136
147
|
readonly adMaximumDisplayMs?: number;
|
|
148
|
+
/** Maximum wait for an inline banner to render or report no-fill/failure. */
|
|
149
|
+
readonly bannerRenderTimeoutMs?: number;
|
|
150
|
+
/** Provider-neutral host preference mapped to the Apps in Toss banner appearance. */
|
|
151
|
+
readonly bannerAppearance?: AitBannerAppearance;
|
|
137
152
|
readonly dependencies?: Partial<AitHostDependencies>;
|
|
138
153
|
}
|
|
139
154
|
export declare function installAitHostBridge(options?: InstallAitHostBridgeOptions): GamePlatformBridge;
|
package/dist/host.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { getTossShareLink, getUserKeyForGame, grantPromotionRewardForGame as grantPromotionReward, IAP, isMinVersionSupported, loadFullScreenAd, openGameCenterLeaderboard, requestNotificationAgreement, share, showFullScreenAd, Storage, submitGameCenterLeaderBoardScore, } from '@apps-in-toss/web-framework';
|
|
1
|
+
import { getTossShareLink, getUserKeyForGame, grantPromotionRewardForGame as grantPromotionReward, IAP, isMinVersionSupported, loadFullScreenAd, openGameCenterLeaderboard, requestNotificationAgreement, share, showFullScreenAd, Storage, submitGameCenterLeaderBoardScore, TossAds, } from '@apps-in-toss/web-framework';
|
|
2
2
|
import { assertBridgeRequest, bridgeStorageLoadProtocol, } from '@mpgd/bridge';
|
|
3
3
|
import { dispatchAitLifecycleEvent } from './lifecycle.js';
|
|
4
4
|
const defaultAdTimeoutMs = 60000;
|
|
5
5
|
const defaultAdLoadQueueTimeoutMs = 5000;
|
|
6
6
|
const defaultAdDisplayStartTimeoutMs = 60000;
|
|
7
7
|
const defaultAdMaximumDisplayMs = 30 * 60000;
|
|
8
|
+
const defaultBannerRenderTimeoutMs = 15000;
|
|
8
9
|
/** Leaves five seconds of headroom inside the native IAP 30-second grant callback. */
|
|
9
10
|
const defaultIapProductGrantTimeoutMs = 25000;
|
|
10
11
|
/** Bounds abandoned checkout UI while still allowing the user to finish an interactive purchase. */
|
|
@@ -53,6 +54,7 @@ const defaultDependencies = {
|
|
|
53
54
|
isMinVersionSupported,
|
|
54
55
|
loadFullScreenAd,
|
|
55
56
|
showFullScreenAd,
|
|
57
|
+
tossAds: TossAds,
|
|
56
58
|
openGameCenterLeaderboard,
|
|
57
59
|
submitGameCenterLeaderBoardScore,
|
|
58
60
|
iap: IAP,
|
|
@@ -80,11 +82,21 @@ export function createAitHostBridge(options = {}) {
|
|
|
80
82
|
const loadedAdGroupIds = new Set();
|
|
81
83
|
const loadingAdGroups = new Map();
|
|
82
84
|
const activeAdGroupIds = new Set();
|
|
85
|
+
const activeBannerAttachments = new Map();
|
|
86
|
+
const bannerMountOwners = new Map();
|
|
87
|
+
const pendingBannerMountSettlements = new Map();
|
|
88
|
+
let bannerInitialization;
|
|
83
89
|
let warnedUnsupportedAdPreload = false;
|
|
84
90
|
const adTimeoutMs = normalizeTimeout(options.adTimeoutMs);
|
|
85
91
|
const adLoadQueueTimeoutMs = normalizeLoadQueueTimeout(options.adLoadQueueTimeoutMs);
|
|
86
92
|
const adDisplayStartTimeoutMs = normalizeDisplayStartTimeout(options.adDisplayStartTimeoutMs);
|
|
87
93
|
const adMaximumDisplayMs = normalizeMaximumDisplayTimeout(options.adMaximumDisplayMs);
|
|
94
|
+
const bannerRenderTimeoutMs = normalizeBannerRenderTimeout(options.bannerRenderTimeoutMs);
|
|
95
|
+
const bannerAppearance = {
|
|
96
|
+
theme: options.bannerAppearance?.theme ?? 'dark',
|
|
97
|
+
tone: options.bannerAppearance?.tone ?? 'blackAndWhite',
|
|
98
|
+
variant: options.bannerAppearance?.variant ?? 'expanded',
|
|
99
|
+
};
|
|
88
100
|
const adLoadCoordinator = {
|
|
89
101
|
active: undefined,
|
|
90
102
|
waitTimeoutMs: adLoadQueueTimeoutMs,
|
|
@@ -116,6 +128,8 @@ export function createAitHostBridge(options = {}) {
|
|
|
116
128
|
&& hasConfiguredAdType(adGroupIds, adPlacementTypes, 'rewarded');
|
|
117
129
|
const interstitialAds = adsSupported
|
|
118
130
|
&& hasConfiguredAdType(adGroupIds, adPlacementTypes, 'interstitial');
|
|
131
|
+
const bannerAds = areBannerAdsSupported(dependencies)
|
|
132
|
+
&& hasConfiguredAdType(adGroupIds, adPlacementTypes, 'banner');
|
|
119
133
|
const nativeIap = isAitIapSupported({
|
|
120
134
|
dependencies,
|
|
121
135
|
products: iapProducts,
|
|
@@ -126,7 +140,8 @@ export function createAitHostBridge(options = {}) {
|
|
|
126
140
|
});
|
|
127
141
|
return ok(request, {
|
|
128
142
|
nativeIap,
|
|
129
|
-
nativeAds: rewardedAds || interstitialAds,
|
|
143
|
+
nativeAds: rewardedAds || interstitialAds || bannerAds,
|
|
144
|
+
bannerAds,
|
|
130
145
|
rewardedAds,
|
|
131
146
|
interstitialAds,
|
|
132
147
|
nativeLeaderboard: isGameCenterSupported(dependencies),
|
|
@@ -315,6 +330,9 @@ export function createAitHostBridge(options = {}) {
|
|
|
315
330
|
if (adGroupId === undefined || placementType === undefined) {
|
|
316
331
|
return createBridgeError(request.id, 'AIT_AD_UNAVAILABLE', `AIT ad placement is unavailable: ${placementId}`);
|
|
317
332
|
}
|
|
333
|
+
if (placementType === 'banner') {
|
|
334
|
+
return ok(request, {});
|
|
335
|
+
}
|
|
318
336
|
if (!isAitNativeMethodSupported(dependencies.loadFullScreenAd)) {
|
|
319
337
|
if (!warnedUnsupportedAdPreload) {
|
|
320
338
|
warnedUnsupportedAdPreload = true;
|
|
@@ -370,6 +388,61 @@ export function createAitHostBridge(options = {}) {
|
|
|
370
388
|
const shown = await withLoadedAdSlot(dependencies, adGroupId, loadedAdGroupIds, loadingAdGroups, adLoadCoordinator, activeAdGroupIds, adTimeoutMs, 'interstitial', showInterstitial);
|
|
371
389
|
return ok(request, shown.acquired ? shown.value : { status: 'unavailable' });
|
|
372
390
|
}
|
|
391
|
+
case 'ads.mountBanner': {
|
|
392
|
+
const placementId = readPlacementId(request.payload);
|
|
393
|
+
const surfaceId = readBannerSurfaceId(request.payload);
|
|
394
|
+
const adGroupId = adGroupIds.get(placementId);
|
|
395
|
+
if (adGroupId === undefined
|
|
396
|
+
|| adPlacementTypes.get(placementId) !== 'banner'
|
|
397
|
+
|| !areBannerAdsSupported(dependencies)) {
|
|
398
|
+
return ok(request, { status: 'unavailable' });
|
|
399
|
+
}
|
|
400
|
+
const target = globalThis.document?.getElementById(surfaceId);
|
|
401
|
+
if (target === null || target === undefined) {
|
|
402
|
+
return ok(request, { status: 'failed' });
|
|
403
|
+
}
|
|
404
|
+
pendingBannerMountSettlements.get(surfaceId)?.settleUnavailable();
|
|
405
|
+
const mountOwner = Symbol(surfaceId);
|
|
406
|
+
bannerMountOwners.set(surfaceId, mountOwner);
|
|
407
|
+
activeBannerAttachments.get(surfaceId)?.destroy();
|
|
408
|
+
activeBannerAttachments.delete(surfaceId);
|
|
409
|
+
const initializeBanner = bannerInitialization
|
|
410
|
+
?? initializeAitBannerAds(dependencies, bannerRenderTimeoutMs);
|
|
411
|
+
void (bannerInitialization = initializeBanner);
|
|
412
|
+
if (!await initializeBanner) {
|
|
413
|
+
bannerInitialization = undefined;
|
|
414
|
+
if (bannerMountOwners.get(surfaceId) === mountOwner) {
|
|
415
|
+
bannerMountOwners.delete(surfaceId);
|
|
416
|
+
}
|
|
417
|
+
return ok(request, { status: 'failed' });
|
|
418
|
+
}
|
|
419
|
+
if (bannerMountOwners.get(surfaceId) !== mountOwner) {
|
|
420
|
+
return ok(request, { status: 'unavailable' });
|
|
421
|
+
}
|
|
422
|
+
activeBannerAttachments.get(surfaceId)?.destroy();
|
|
423
|
+
activeBannerAttachments.delete(surfaceId);
|
|
424
|
+
const result = await attachAitBanner({
|
|
425
|
+
dependencies,
|
|
426
|
+
adGroupId,
|
|
427
|
+
surfaceId,
|
|
428
|
+
target,
|
|
429
|
+
timeoutMs: bannerRenderTimeoutMs,
|
|
430
|
+
appearance: bannerAppearance,
|
|
431
|
+
activeAttachments: activeBannerAttachments,
|
|
432
|
+
mountOwner,
|
|
433
|
+
mountOwners: bannerMountOwners,
|
|
434
|
+
pendingSettlements: pendingBannerMountSettlements,
|
|
435
|
+
});
|
|
436
|
+
return ok(request, result);
|
|
437
|
+
}
|
|
438
|
+
case 'ads.unmountBanner': {
|
|
439
|
+
const surfaceId = readBannerSurfaceId(request.payload);
|
|
440
|
+
pendingBannerMountSettlements.get(surfaceId)?.settleUnavailable();
|
|
441
|
+
bannerMountOwners.delete(surfaceId);
|
|
442
|
+
activeBannerAttachments.get(surfaceId)?.destroy();
|
|
443
|
+
activeBannerAttachments.delete(surfaceId);
|
|
444
|
+
return ok(request, {});
|
|
445
|
+
}
|
|
373
446
|
case 'leaderboard.submitScore': {
|
|
374
447
|
if (!isGameCenterSupported(dependencies)) {
|
|
375
448
|
return ok(request, { submitted: false });
|
|
@@ -1837,6 +1910,122 @@ function areFullScreenAdsSupported(dependencies) {
|
|
|
1837
1910
|
return isAitNativeMethodSupported(dependencies.loadFullScreenAd)
|
|
1838
1911
|
&& isAitNativeMethodSupported(dependencies.showFullScreenAd);
|
|
1839
1912
|
}
|
|
1913
|
+
function areBannerAdsSupported(dependencies) {
|
|
1914
|
+
return isAitNativeMethodSupported(dependencies.tossAds.initialize)
|
|
1915
|
+
&& isAitNativeMethodSupported(dependencies.tossAds.attachBanner);
|
|
1916
|
+
}
|
|
1917
|
+
function initializeAitBannerAds(dependencies, timeoutMs) {
|
|
1918
|
+
return new Promise((resolve) => {
|
|
1919
|
+
let settled = false;
|
|
1920
|
+
const finish = (initialized) => {
|
|
1921
|
+
if (settled) {
|
|
1922
|
+
return;
|
|
1923
|
+
}
|
|
1924
|
+
settled = true;
|
|
1925
|
+
globalThis.clearTimeout(timer);
|
|
1926
|
+
resolve(initialized);
|
|
1927
|
+
};
|
|
1928
|
+
const timer = globalThis.setTimeout(() => finish(false), timeoutMs);
|
|
1929
|
+
try {
|
|
1930
|
+
dependencies.tossAds.initialize({
|
|
1931
|
+
callbacks: {
|
|
1932
|
+
onInitialized: () => finish(true),
|
|
1933
|
+
onInitializationFailed: () => finish(false),
|
|
1934
|
+
},
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
catch (error) {
|
|
1938
|
+
console.warn('Failed to initialize AIT banner ads.', error);
|
|
1939
|
+
finish(false);
|
|
1940
|
+
}
|
|
1941
|
+
});
|
|
1942
|
+
}
|
|
1943
|
+
async function attachAitBanner(input) {
|
|
1944
|
+
return new Promise((resolve) => {
|
|
1945
|
+
let settled = false;
|
|
1946
|
+
let terminalStatus;
|
|
1947
|
+
let attachment;
|
|
1948
|
+
const finish = (requestedStatus) => {
|
|
1949
|
+
const ownsSurface = input.mountOwners.get(input.surfaceId) === input.mountOwner;
|
|
1950
|
+
const status = requestedStatus === 'mounted' && !ownsSurface
|
|
1951
|
+
? 'unavailable'
|
|
1952
|
+
: requestedStatus;
|
|
1953
|
+
if (settled) {
|
|
1954
|
+
if (status !== 'mounted' && input.activeAttachments.get(input.surfaceId) === attachment) {
|
|
1955
|
+
attachment?.destroy();
|
|
1956
|
+
input.activeAttachments.delete(input.surfaceId);
|
|
1957
|
+
}
|
|
1958
|
+
if (status !== 'mounted' && ownsSurface) {
|
|
1959
|
+
input.mountOwners.delete(input.surfaceId);
|
|
1960
|
+
}
|
|
1961
|
+
return;
|
|
1962
|
+
}
|
|
1963
|
+
settled = true;
|
|
1964
|
+
terminalStatus = status;
|
|
1965
|
+
globalThis.clearTimeout(timer);
|
|
1966
|
+
if (input.pendingSettlements.get(input.surfaceId)?.mountOwner === input.mountOwner) {
|
|
1967
|
+
input.pendingSettlements.delete(input.surfaceId);
|
|
1968
|
+
}
|
|
1969
|
+
if (status !== 'mounted') {
|
|
1970
|
+
attachment?.destroy();
|
|
1971
|
+
if (input.activeAttachments.get(input.surfaceId) === attachment) {
|
|
1972
|
+
input.activeAttachments.delete(input.surfaceId);
|
|
1973
|
+
}
|
|
1974
|
+
if (ownsSurface) {
|
|
1975
|
+
input.mountOwners.delete(input.surfaceId);
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1978
|
+
resolve({ status });
|
|
1979
|
+
};
|
|
1980
|
+
const timer = globalThis.setTimeout(() => finish('failed'), input.timeoutMs);
|
|
1981
|
+
input.pendingSettlements.set(input.surfaceId, {
|
|
1982
|
+
mountOwner: input.mountOwner,
|
|
1983
|
+
settleUnavailable: () => finish('unavailable'),
|
|
1984
|
+
});
|
|
1985
|
+
try {
|
|
1986
|
+
const sdkAttachment = input.dependencies.tossAds.attachBanner(input.adGroupId, input.target, {
|
|
1987
|
+
theme: input.appearance.theme,
|
|
1988
|
+
tone: input.appearance.tone,
|
|
1989
|
+
variant: input.appearance.variant,
|
|
1990
|
+
callbacks: {
|
|
1991
|
+
onAdRendered: () => finish('mounted'),
|
|
1992
|
+
onNoFill: () => finish('unavailable'),
|
|
1993
|
+
onAdFailedToRender: (payload) => {
|
|
1994
|
+
console.warn('Failed to render an AIT banner ad.', input.adGroupId, payload.error);
|
|
1995
|
+
finish('failed');
|
|
1996
|
+
},
|
|
1997
|
+
},
|
|
1998
|
+
});
|
|
1999
|
+
let attachmentDestroyed = false;
|
|
2000
|
+
attachment = {
|
|
2001
|
+
destroy() {
|
|
2002
|
+
if (!attachmentDestroyed) {
|
|
2003
|
+
attachmentDestroyed = true;
|
|
2004
|
+
sdkAttachment.destroy();
|
|
2005
|
+
}
|
|
2006
|
+
},
|
|
2007
|
+
};
|
|
2008
|
+
if (terminalStatus === 'unavailable' || terminalStatus === 'failed') {
|
|
2009
|
+
attachment.destroy();
|
|
2010
|
+
return;
|
|
2011
|
+
}
|
|
2012
|
+
if (input.mountOwners.get(input.surfaceId) !== input.mountOwner) {
|
|
2013
|
+
attachment.destroy();
|
|
2014
|
+
finish('unavailable');
|
|
2015
|
+
return;
|
|
2016
|
+
}
|
|
2017
|
+
const existingAttachment = input.activeAttachments.get(input.surfaceId);
|
|
2018
|
+
if (existingAttachment !== undefined && existingAttachment !== attachment) {
|
|
2019
|
+
existingAttachment.destroy();
|
|
2020
|
+
}
|
|
2021
|
+
input.activeAttachments.set(input.surfaceId, attachment);
|
|
2022
|
+
}
|
|
2023
|
+
catch (error) {
|
|
2024
|
+
console.warn('Failed to attach an AIT banner ad.', input.adGroupId, error);
|
|
2025
|
+
finish('failed');
|
|
2026
|
+
}
|
|
2027
|
+
});
|
|
2028
|
+
}
|
|
1840
2029
|
function isAitNativeMethodSupported(method) {
|
|
1841
2030
|
return isCapabilitySupported(() => method.isSupported?.() === true);
|
|
1842
2031
|
}
|
|
@@ -1930,6 +2119,9 @@ function normalizeDisplayStartTimeout(value) {
|
|
|
1930
2119
|
function normalizeMaximumDisplayTimeout(value) {
|
|
1931
2120
|
return normalizePositiveTimeout(value, defaultAdMaximumDisplayMs, 'AIT ad maximum display timeout must be a positive finite number.');
|
|
1932
2121
|
}
|
|
2122
|
+
function normalizeBannerRenderTimeout(value) {
|
|
2123
|
+
return normalizePositiveTimeout(value, defaultBannerRenderTimeoutMs, 'AIT banner render timeout must be a positive finite number.');
|
|
2124
|
+
}
|
|
1933
2125
|
function normalizeIapProductGrantTimeout(value) {
|
|
1934
2126
|
const timeout = normalizePositiveTimeout(value, defaultIapProductGrantTimeoutMs, 'AIT IAP product-grant timeout must be a positive finite number.');
|
|
1935
2127
|
if (timeout > defaultIapProductGrantTimeoutMs) {
|
|
@@ -1960,6 +2152,13 @@ function readPlacementId(payload) {
|
|
|
1960
2152
|
}
|
|
1961
2153
|
return placementId;
|
|
1962
2154
|
}
|
|
2155
|
+
function readBannerSurfaceId(payload) {
|
|
2156
|
+
const surfaceId = readPayloadRecord(payload).surfaceId;
|
|
2157
|
+
if (typeof surfaceId !== 'string' || surfaceId.length === 0) {
|
|
2158
|
+
throw new TypeError('AIT banner surfaceId must be a valid non-empty element id.');
|
|
2159
|
+
}
|
|
2160
|
+
return surfaceId;
|
|
2161
|
+
}
|
|
1963
2162
|
function readIdempotencyKey(payload, fallback) {
|
|
1964
2163
|
const value = readPayloadRecord(payload).idempotencyKey;
|
|
1965
2164
|
return typeof value === 'string' && value.length > 0 ? value : fallback;
|
package/dist/index.js
CHANGED
|
@@ -58,6 +58,8 @@ export function createAitPlatformGateway(input) {
|
|
|
58
58
|
preload: (payload) => request('ads.preload', payload),
|
|
59
59
|
showRewarded: (payload) => request('ads.showRewarded', payload),
|
|
60
60
|
showInterstitial: (payload) => request('ads.showInterstitial', payload),
|
|
61
|
+
mountBanner: (payload) => request('ads.mountBanner', payload),
|
|
62
|
+
unmountBanner: (payload) => request('ads.unmountBanner', payload),
|
|
61
63
|
},
|
|
62
64
|
leaderboard: {
|
|
63
65
|
submitScore: (payload) => request('leaderboard.submitScore', payload),
|
|
@@ -95,6 +97,7 @@ export function createAitSandboxBridge(options = {}) {
|
|
|
95
97
|
return ok(input, {
|
|
96
98
|
nativeIap: true,
|
|
97
99
|
nativeAds: true,
|
|
100
|
+
bannerAds: false,
|
|
98
101
|
rewardedAds: true,
|
|
99
102
|
interstitialAds: true,
|
|
100
103
|
nativeLeaderboard: true,
|
|
@@ -178,6 +181,10 @@ export function createAitSandboxBridge(options = {}) {
|
|
|
178
181
|
return ok(input, {
|
|
179
182
|
status: 'shown',
|
|
180
183
|
});
|
|
184
|
+
case 'ads.mountBanner':
|
|
185
|
+
return ok(input, { status: 'unavailable' });
|
|
186
|
+
case 'ads.unmountBanner':
|
|
187
|
+
return ok(input, {});
|
|
181
188
|
case 'leaderboard.submitScore':
|
|
182
189
|
return ok(input, {
|
|
183
190
|
submitted: true,
|
package/dist/local-mock.d.ts
CHANGED
|
@@ -30,6 +30,22 @@ export declare const loadFullScreenAd: ((_callbacks: unknown) => (() => void)) &
|
|
|
30
30
|
export declare const showFullScreenAd: ((_callbacks: unknown) => (() => void)) & {
|
|
31
31
|
isSupported: typeof unsupported;
|
|
32
32
|
};
|
|
33
|
+
export declare const TossAds: {
|
|
34
|
+
initialize: ((_options: unknown) => void) & {
|
|
35
|
+
isSupported: typeof unsupported;
|
|
36
|
+
};
|
|
37
|
+
attachBanner: ((_adGroupId: string, _target: string | HTMLElement, _options?: unknown) => {
|
|
38
|
+
destroy(): void;
|
|
39
|
+
}) & {
|
|
40
|
+
isSupported: typeof unsupported;
|
|
41
|
+
};
|
|
42
|
+
destroy: ((_slotId: string) => void) & {
|
|
43
|
+
isSupported: typeof unsupported;
|
|
44
|
+
};
|
|
45
|
+
destroyAll: (() => void) & {
|
|
46
|
+
isSupported: typeof unsupported;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
33
49
|
export declare function openGameCenterLeaderboard(): Promise<void>;
|
|
34
50
|
export declare function submitGameCenterLeaderBoardScore(): Promise<{
|
|
35
51
|
readonly statusCode: 'ERROR';
|
package/dist/local-mock.js
CHANGED
|
@@ -39,6 +39,14 @@ export const grantPromotionRewardForGame = Object.assign(async () => 'ERROR', {
|
|
|
39
39
|
export const requestNotificationAgreement = Object.assign((_callbacks) => noOpSubscription(), { isSupported: unsupported });
|
|
40
40
|
export const loadFullScreenAd = Object.assign((_callbacks) => noOpSubscription(), { isSupported: unsupported });
|
|
41
41
|
export const showFullScreenAd = Object.assign((_callbacks) => noOpSubscription(), { isSupported: unsupported });
|
|
42
|
+
export const TossAds = {
|
|
43
|
+
initialize: Object.assign((_options) => { }, { isSupported: unsupported }),
|
|
44
|
+
attachBanner: Object.assign((_adGroupId, _target, _options) => ({
|
|
45
|
+
destroy() { },
|
|
46
|
+
}), { isSupported: unsupported }),
|
|
47
|
+
destroy: Object.assign((_slotId) => { }, { isSupported: unsupported }),
|
|
48
|
+
destroyAll: Object.assign(() => { }, { isSupported: unsupported }),
|
|
49
|
+
};
|
|
42
50
|
export async function openGameCenterLeaderboard() { }
|
|
43
51
|
export async function submitGameCenterLeaderBoardScore() {
|
|
44
52
|
return { statusCode: 'ERROR' };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpgd/adapter-ait",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Apps in Toss WebView platform adapter for mpgd games.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"dist"
|
|
52
52
|
],
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@mpgd/bridge": "0.
|
|
55
|
-
"@mpgd/platform": "0.
|
|
54
|
+
"@mpgd/bridge": "0.9.0",
|
|
55
|
+
"@mpgd/platform": "0.10.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
58
|
"@apps-in-toss/web-framework": ">=3.0.0 <4"
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@apps-in-toss/web-framework": "3.
|
|
66
|
+
"@apps-in-toss/web-framework": "3.1.1",
|
|
67
67
|
"ttsc": "0.18.4",
|
|
68
68
|
"typescript": "7.0.2",
|
|
69
69
|
"vitest": "^4.0.0"
|