@mpgd/adapter-verse8 0.3.12 → 0.4.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-provider.d.ts +17 -0
- package/dist/ad-provider.js +276 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +9 -88
- package/package.json +7 -5
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type AdProvider } from '@mpgd/platform/ads';
|
|
2
|
+
import type { Verse8AdsClient } from './index.js';
|
|
3
|
+
export interface Verse8AdPresentationEvent {
|
|
4
|
+
readonly requestId: string;
|
|
5
|
+
readonly sequence: number;
|
|
6
|
+
readonly state: 'open' | 'closed' | 'not-started' | 'unknown';
|
|
7
|
+
}
|
|
8
|
+
/** Trusted host facts, scoped to the original SDK request. Reward telemetry is not closure. */
|
|
9
|
+
export interface Verse8AdPresentationSource {
|
|
10
|
+
subscribe(listener: (event: Verse8AdPresentationEvent) => void): () => void;
|
|
11
|
+
}
|
|
12
|
+
export declare function createVerse8AdProvider(input: {
|
|
13
|
+
readonly client: Verse8AdsClient;
|
|
14
|
+
readonly resolvePlacement?: (placementId: string) => string | undefined;
|
|
15
|
+
readonly presentation?: Verse8AdPresentationSource;
|
|
16
|
+
readonly timeoutMs?: number;
|
|
17
|
+
}): AdProvider;
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { adProtocol, adProtocolVersion, assertAdPresentationEvent, assertAdShowInput, assertAdShowResult, } from '@mpgd/platform/ads';
|
|
2
|
+
import { verse8AdsRewardEvidenceSchema } from './ads-contract.js';
|
|
3
|
+
const owners = new WeakMap();
|
|
4
|
+
export function createVerse8AdProvider(input) {
|
|
5
|
+
const id = 'verse8-ads';
|
|
6
|
+
const timeoutMs = input.timeoutMs ?? 30000;
|
|
7
|
+
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2147483647) {
|
|
8
|
+
throw new RangeError('Verse8 ad timeout must be a positive timer duration.');
|
|
9
|
+
}
|
|
10
|
+
const listeners = new Set();
|
|
11
|
+
function availability(request) {
|
|
12
|
+
const placement = input.resolvePlacement?.(request.placementId);
|
|
13
|
+
if (typeof placement !== 'string' || placement.trim() === '' || placement.length > 512) {
|
|
14
|
+
return {
|
|
15
|
+
state: 'configuration-required',
|
|
16
|
+
reason: 'configuration-required',
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
// SDK 0.4 resolves rewarded H5 ads at adViewed, before adBreakDone. It has
|
|
20
|
+
// no reliable rewarded closure port; require a trusted host integration.
|
|
21
|
+
if (request.format === 'rewarded' && input.presentation === undefined) {
|
|
22
|
+
return {
|
|
23
|
+
state: 'configuration-required',
|
|
24
|
+
reason: 'configuration-required',
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const owner = owners.get(input.client);
|
|
28
|
+
if (owner?.state === 'unknown') {
|
|
29
|
+
return {
|
|
30
|
+
state: 'action-required',
|
|
31
|
+
reason: 'action-required',
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
if (owner !== undefined) {
|
|
35
|
+
return { state: 'temporarily-unavailable', reason: 'busy' };
|
|
36
|
+
}
|
|
37
|
+
return { state: 'available' };
|
|
38
|
+
}
|
|
39
|
+
async function show(supplied) {
|
|
40
|
+
const request = assertAdShowInput(supplied);
|
|
41
|
+
const make = (value) => assertAdShowResult({ providerId: id, invocationId: request.invocationId, format: request.format, ...value });
|
|
42
|
+
const negative = (reason, outcome = 'unavailable') => make({
|
|
43
|
+
outcome,
|
|
44
|
+
presentation: 'not-started',
|
|
45
|
+
eligibility: request.format === 'rewarded' ? 'not-earned' : 'not-applicable',
|
|
46
|
+
reason,
|
|
47
|
+
});
|
|
48
|
+
const available = availability(request);
|
|
49
|
+
if (available.state !== 'available') {
|
|
50
|
+
return negative(available.reason ?? 'configuration-required');
|
|
51
|
+
}
|
|
52
|
+
const placement = input.resolvePlacement?.(request.placementId);
|
|
53
|
+
if (placement === undefined) {
|
|
54
|
+
return negative('configuration-required');
|
|
55
|
+
}
|
|
56
|
+
const owner = { state: 'requested' };
|
|
57
|
+
owners.set(input.client, owner);
|
|
58
|
+
const release = () => {
|
|
59
|
+
if (owners.get(input.client) === owner) {
|
|
60
|
+
owners.delete(input.client);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
let started = false;
|
|
64
|
+
let closed = false;
|
|
65
|
+
let called = false;
|
|
66
|
+
let delivered = false;
|
|
67
|
+
let sdkSettled = false;
|
|
68
|
+
let nativeSequence = 0;
|
|
69
|
+
let sequence = 0;
|
|
70
|
+
let earned;
|
|
71
|
+
let notEarned = false;
|
|
72
|
+
let didNotStart = false;
|
|
73
|
+
const candidate = {
|
|
74
|
+
schema: verse8AdsRewardEvidenceSchema,
|
|
75
|
+
payload: { requestId: request.invocationId, placementId: placement },
|
|
76
|
+
};
|
|
77
|
+
let unsubscribe;
|
|
78
|
+
let cleaned = false;
|
|
79
|
+
let resolve;
|
|
80
|
+
const pending = new Promise((done) => {
|
|
81
|
+
resolve = done;
|
|
82
|
+
});
|
|
83
|
+
const clean = () => {
|
|
84
|
+
if (cleaned || !closed || !sdkSettled || unsubscribe === undefined) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
cleaned = true;
|
|
88
|
+
try {
|
|
89
|
+
unsubscribe();
|
|
90
|
+
}
|
|
91
|
+
catch { /* Native closure is already known. */ }
|
|
92
|
+
};
|
|
93
|
+
const emit = (event) => {
|
|
94
|
+
const safe = assertAdPresentationEvent({
|
|
95
|
+
...event,
|
|
96
|
+
providerId: id,
|
|
97
|
+
invocationId: request.invocationId,
|
|
98
|
+
sequence: ++sequence,
|
|
99
|
+
});
|
|
100
|
+
for (const listener of [...listeners]) {
|
|
101
|
+
try {
|
|
102
|
+
void Promise.resolve(listener(safe)).catch(() => undefined);
|
|
103
|
+
}
|
|
104
|
+
catch { /* Isolate observation. */ }
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const eligibility = () => {
|
|
108
|
+
if (request.format === 'interstitial') {
|
|
109
|
+
return 'not-applicable';
|
|
110
|
+
}
|
|
111
|
+
if (notEarned) {
|
|
112
|
+
return 'not-earned';
|
|
113
|
+
}
|
|
114
|
+
return earned === undefined ? 'unknown' : 'eligible';
|
|
115
|
+
};
|
|
116
|
+
const result = () => make({
|
|
117
|
+
outcome: closed ? 'shown' : 'pending',
|
|
118
|
+
presentation: closed ? 'closed' : 'unknown',
|
|
119
|
+
eligibility: eligibility(),
|
|
120
|
+
...(!closed ? { reason: 'outcome-unknown' } : {}),
|
|
121
|
+
...(earned === undefined ? {} : { evidence: earned }),
|
|
122
|
+
...(request.format === 'rewarded' && !notEarned ? { claimEvidence: candidate } : {}),
|
|
123
|
+
});
|
|
124
|
+
const finish = (value) => {
|
|
125
|
+
if (!delivered) {
|
|
126
|
+
delivered = true;
|
|
127
|
+
clearTimeout(timer);
|
|
128
|
+
resolve(value);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
const unknown = () => {
|
|
132
|
+
if (!closed) {
|
|
133
|
+
owner.state = 'unknown';
|
|
134
|
+
emit({ type: 'unknown' });
|
|
135
|
+
}
|
|
136
|
+
finish(result());
|
|
137
|
+
};
|
|
138
|
+
const close = () => {
|
|
139
|
+
if (closed) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
closed = true;
|
|
143
|
+
release();
|
|
144
|
+
emit({ type: 'closed' });
|
|
145
|
+
finish(result());
|
|
146
|
+
clean();
|
|
147
|
+
};
|
|
148
|
+
try {
|
|
149
|
+
unsubscribe = input.presentation?.subscribe((event) => {
|
|
150
|
+
if (!called || event.requestId !== request.invocationId || closed || !Number.isSafeInteger(event.sequence) || event.sequence <= nativeSequence) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (!['open', 'closed', 'not-started', 'unknown'].includes(event.state)) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
nativeSequence = event.sequence;
|
|
157
|
+
if (event.state === 'open') {
|
|
158
|
+
if (!started) {
|
|
159
|
+
started = true;
|
|
160
|
+
owner.state = 'open';
|
|
161
|
+
emit({ type: 'started' });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else if (event.state === 'closed') {
|
|
165
|
+
close();
|
|
166
|
+
}
|
|
167
|
+
else if (event.state === 'not-started') {
|
|
168
|
+
if (started || earned !== undefined) {
|
|
169
|
+
unknown();
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
closed = true;
|
|
173
|
+
didNotStart = true;
|
|
174
|
+
notEarned = true;
|
|
175
|
+
release();
|
|
176
|
+
emit({ type: 'failed', reason: 'transient-failure' });
|
|
177
|
+
finish(negative('transient-failure', 'failed'));
|
|
178
|
+
clean();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
unknown();
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
release();
|
|
188
|
+
return negative('transient-failure', 'failed');
|
|
189
|
+
}
|
|
190
|
+
emit({
|
|
191
|
+
type: 'requested',
|
|
192
|
+
...(request.format === 'rewarded' && !notEarned ? { claimEvidence: candidate } : {}),
|
|
193
|
+
});
|
|
194
|
+
const timer = setTimeout(unknown, timeoutMs);
|
|
195
|
+
called = true;
|
|
196
|
+
const sdkInput = {
|
|
197
|
+
placementId: placement,
|
|
198
|
+
requestId: request.invocationId,
|
|
199
|
+
timeoutMs,
|
|
200
|
+
meta: { logicalPlacementId: request.placementId },
|
|
201
|
+
};
|
|
202
|
+
try {
|
|
203
|
+
const promise = request.format === 'rewarded'
|
|
204
|
+
? input.client.showRewarded(sdkInput)
|
|
205
|
+
: input.client.showInterstitial(sdkInput);
|
|
206
|
+
void Promise.resolve(promise).then((value) => {
|
|
207
|
+
sdkSettled = true;
|
|
208
|
+
if (value.requestId !== request.invocationId) {
|
|
209
|
+
unknown();
|
|
210
|
+
clean();
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (didNotStart) {
|
|
214
|
+
clean();
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (value.status === 'rewarded' && request.format === 'rewarded') {
|
|
218
|
+
earned = candidate;
|
|
219
|
+
if (!started && !closed) {
|
|
220
|
+
started = true;
|
|
221
|
+
owner.state = 'open';
|
|
222
|
+
emit({ type: 'started' });
|
|
223
|
+
}
|
|
224
|
+
emit({ type: 'reward-earned', evidence: candidate });
|
|
225
|
+
// Rewarded completion is eligibility only. The host must close UI.
|
|
226
|
+
if (closed) {
|
|
227
|
+
finish(result());
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
else if (value.status === 'dismissed') {
|
|
231
|
+
notEarned = earned === undefined;
|
|
232
|
+
close();
|
|
233
|
+
}
|
|
234
|
+
else if (value.status === 'failed' && !started && !closed && (value.error.code === 'unsupported_env' || value.error.code === 'busy')) {
|
|
235
|
+
closed = true;
|
|
236
|
+
release();
|
|
237
|
+
emit({ type: 'failed', reason: value.error.code === 'busy' ? 'busy' : 'unsupported' });
|
|
238
|
+
finish(negative(value.error.code === 'busy' ? 'busy' : 'unsupported'));
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
unknown();
|
|
242
|
+
}
|
|
243
|
+
clean();
|
|
244
|
+
}, () => { sdkSettled = true; unknown(); clean(); }).catch(() => { sdkSettled = true; unknown(); clean(); });
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
sdkSettled = true;
|
|
248
|
+
unknown();
|
|
249
|
+
clean();
|
|
250
|
+
}
|
|
251
|
+
return pending;
|
|
252
|
+
}
|
|
253
|
+
return {
|
|
254
|
+
id,
|
|
255
|
+
protocol: adProtocol,
|
|
256
|
+
protocolVersion: adProtocolVersion,
|
|
257
|
+
rewardSignal: 'delayed',
|
|
258
|
+
getAvailability: async (request) => availability(request),
|
|
259
|
+
async preload(request) {
|
|
260
|
+
const available = availability(request);
|
|
261
|
+
return available.state === 'available'
|
|
262
|
+
? { status: 'deferred' }
|
|
263
|
+
: {
|
|
264
|
+
status: 'unavailable',
|
|
265
|
+
...(available.reason === undefined ? {} : { reason: available.reason }),
|
|
266
|
+
};
|
|
267
|
+
},
|
|
268
|
+
show,
|
|
269
|
+
subscribe(listener) {
|
|
270
|
+
listeners.add(listener);
|
|
271
|
+
return () => {
|
|
272
|
+
listeners.delete(listener);
|
|
273
|
+
};
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { type InterstitialAdResult as Verse8InterstitialAdResult, type RewardedAdResult as Verse8RewardedAdResult } from '@verse8/ads';
|
|
2
2
|
import { type CatalogTarget, type ProductCatalog } from '@mpgd/catalog';
|
|
3
3
|
import { type Entitlement, type LogicalAdPlacementId, type LogicalProductId, type PlatformGateway, type ProductType, type StorageAdapter } from '@mpgd/platform';
|
|
4
|
+
import { type Verse8AdPresentationSource } from './ad-provider.js';
|
|
4
5
|
export { verse8AdsRewardEvidenceSchema } from './ads-contract.js';
|
|
6
|
+
export type { Verse8AdPresentationEvent, Verse8AdPresentationSource } from './ad-provider.js';
|
|
5
7
|
export interface Verse8Credential {
|
|
6
8
|
readonly account: `0x${string}`;
|
|
7
9
|
readonly verse: string;
|
|
@@ -31,11 +33,13 @@ export interface Verse8AdsClient {
|
|
|
31
33
|
showRewarded(input: {
|
|
32
34
|
readonly placementId: string;
|
|
33
35
|
readonly timeoutMs?: number;
|
|
36
|
+
readonly requestId?: string;
|
|
34
37
|
readonly meta?: Record<string, unknown>;
|
|
35
38
|
}): Promise<Verse8RewardedAdResult>;
|
|
36
39
|
showInterstitial(input: {
|
|
37
40
|
readonly placementId: string;
|
|
38
41
|
readonly timeoutMs?: number;
|
|
42
|
+
readonly requestId?: string;
|
|
39
43
|
readonly meta?: Record<string, unknown>;
|
|
40
44
|
}): Promise<Verse8InterstitialAdResult>;
|
|
41
45
|
}
|
|
@@ -84,6 +88,8 @@ export interface Verse8PlatformGatewayOptions {
|
|
|
84
88
|
readonly authClient?: Verse8AuthClient;
|
|
85
89
|
readonly adsClient?: Verse8AdsClient;
|
|
86
90
|
readonly adsTimeoutMs?: number;
|
|
91
|
+
/** Required for rewarded v2: SDK 0.4 reward completion does not prove native closure. */
|
|
92
|
+
readonly adPresentation?: Verse8AdPresentationSource;
|
|
87
93
|
readonly resolveAdPlacementId?: (placementId: LogicalAdPlacementId) => string | undefined;
|
|
88
94
|
readonly vxShop?: Verse8CommerceOptions;
|
|
89
95
|
readonly agent8Storage?: Verse8Agent8StorageClient;
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,8 @@ import { Verse8Ads, } from '@verse8/ads';
|
|
|
2
2
|
import { Verse8, VXShop } from '@verse8/platform/vanilla';
|
|
3
3
|
import { resolveProductPlatformId } from '@mpgd/catalog';
|
|
4
4
|
import { createUnsupportedCapabilities, } from '@mpgd/platform';
|
|
5
|
-
import {
|
|
5
|
+
import { createVerse8AdProvider } from './ad-provider.js';
|
|
6
|
+
import { toAdAdapter } from '@mpgd/platform/ads';
|
|
6
7
|
import { defaultVerse8CatalogTarget } from './catalog-target.js';
|
|
7
8
|
export { verse8AdsRewardEvidenceSchema } from './ads-contract.js';
|
|
8
9
|
export function createVerse8CommerceProducts(catalog, target = defaultVerse8CatalogTarget) {
|
|
@@ -23,6 +24,12 @@ export function createVerse8PlatformGateway(options = {}) {
|
|
|
23
24
|
const authClient = options.authClient ?? createDefaultAuthClient();
|
|
24
25
|
const adsClient = options.adsClient ?? Verse8Ads;
|
|
25
26
|
const adsAvailable = options.resolveAdPlacementId !== undefined;
|
|
27
|
+
const ads = toAdAdapter(createVerse8AdProvider({
|
|
28
|
+
client: adsClient,
|
|
29
|
+
...(options.resolveAdPlacementId === undefined ? {} : { resolvePlacement: options.resolveAdPlacementId }),
|
|
30
|
+
...(options.adPresentation === undefined ? {} : { presentation: options.adPresentation }),
|
|
31
|
+
...(options.adsTimeoutMs === undefined ? {} : { timeoutMs: options.adsTimeoutMs }),
|
|
32
|
+
}));
|
|
26
33
|
const commerce = createVerse8Commerce(options.vxShop);
|
|
27
34
|
const pauseListeners = new Set();
|
|
28
35
|
const resumeListeners = new Set();
|
|
@@ -56,87 +63,7 @@ export function createVerse8PlatformGateway(options = {}) {
|
|
|
56
63
|
},
|
|
57
64
|
},
|
|
58
65
|
commerce: commerce ?? createUnavailableVerse8Commerce(),
|
|
59
|
-
ads
|
|
60
|
-
async preload() { },
|
|
61
|
-
async showRewarded(input) {
|
|
62
|
-
const placementId = options.resolveAdPlacementId?.(input.placementId);
|
|
63
|
-
if (placementId === undefined) {
|
|
64
|
-
return unavailableReward();
|
|
65
|
-
}
|
|
66
|
-
try {
|
|
67
|
-
const result = await adsClient.showRewarded({
|
|
68
|
-
placementId,
|
|
69
|
-
...(options.adsTimeoutMs === undefined
|
|
70
|
-
? {}
|
|
71
|
-
: { timeoutMs: options.adsTimeoutMs }),
|
|
72
|
-
meta: {
|
|
73
|
-
logicalPlacementId: input.placementId,
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
|
-
if (result.status === 'rewarded') {
|
|
77
|
-
// The SDK callback is a claim candidate only. `requestId` is a Verse8
|
|
78
|
-
// impression id, not a ledger entry; the backend verifier consumes it
|
|
79
|
-
// from the evidence payload before any reward is granted.
|
|
80
|
-
return {
|
|
81
|
-
status: 'completed',
|
|
82
|
-
rewardGranted: false,
|
|
83
|
-
evidence: {
|
|
84
|
-
schema: verse8AdsRewardEvidenceSchema,
|
|
85
|
-
payload: {
|
|
86
|
-
requestId: result.requestId,
|
|
87
|
-
placementId,
|
|
88
|
-
...(result.platform === undefined ? {} : { platform: result.platform }),
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
if (result.status === 'dismissed') {
|
|
94
|
-
return {
|
|
95
|
-
status: 'skipped',
|
|
96
|
-
rewardGranted: false,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
return result.error.code === 'unsupported_env'
|
|
100
|
-
? unavailableReward()
|
|
101
|
-
: {
|
|
102
|
-
status: 'failed',
|
|
103
|
-
rewardGranted: false,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
catch {
|
|
107
|
-
return {
|
|
108
|
-
status: 'failed',
|
|
109
|
-
rewardGranted: false,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
},
|
|
113
|
-
async showInterstitial(input) {
|
|
114
|
-
const placementId = options.resolveAdPlacementId?.(input.placementId);
|
|
115
|
-
if (placementId === undefined) {
|
|
116
|
-
return { status: 'unavailable' };
|
|
117
|
-
}
|
|
118
|
-
try {
|
|
119
|
-
const result = await adsClient.showInterstitial({
|
|
120
|
-
placementId,
|
|
121
|
-
...(options.adsTimeoutMs === undefined
|
|
122
|
-
? {}
|
|
123
|
-
: { timeoutMs: options.adsTimeoutMs }),
|
|
124
|
-
meta: {
|
|
125
|
-
logicalPlacementId: input.placementId,
|
|
126
|
-
},
|
|
127
|
-
});
|
|
128
|
-
if (result.status === 'dismissed') {
|
|
129
|
-
return { status: 'shown' };
|
|
130
|
-
}
|
|
131
|
-
return result.error.code === 'unsupported_env'
|
|
132
|
-
? { status: 'unavailable' }
|
|
133
|
-
: { status: 'skipped' };
|
|
134
|
-
}
|
|
135
|
-
catch {
|
|
136
|
-
return { status: 'skipped' };
|
|
137
|
-
}
|
|
138
|
-
},
|
|
139
|
-
},
|
|
66
|
+
ads,
|
|
140
67
|
leaderboard: {
|
|
141
68
|
async submitScore() {
|
|
142
69
|
return {
|
|
@@ -318,12 +245,6 @@ function failedPurchase() {
|
|
|
318
245
|
function canOpenDefaultVerse8Shop() {
|
|
319
246
|
return typeof window !== 'undefined' && window.parent !== window;
|
|
320
247
|
}
|
|
321
|
-
function unavailableReward() {
|
|
322
|
-
return {
|
|
323
|
-
status: 'unavailable',
|
|
324
|
-
rewardGranted: false,
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
248
|
function createDefaultAuthClient() {
|
|
328
249
|
return {
|
|
329
250
|
getUser(options) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpgd/adapter-verse8",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Verse8 iframe platform adapter for mpgd games.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -43,14 +43,16 @@
|
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@verse8/ads": "0.4.0",
|
|
45
45
|
"@verse8/platform": "2.1.0",
|
|
46
|
-
"@mpgd/catalog": "0.7.
|
|
47
|
-
"@mpgd/game-services": "0.
|
|
48
|
-
"@mpgd/platform": "0.
|
|
46
|
+
"@mpgd/catalog": "0.7.7",
|
|
47
|
+
"@mpgd/game-services": "0.18.0",
|
|
48
|
+
"@mpgd/platform": "0.15.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
+
"@types/node": "^24.0.0",
|
|
51
52
|
"ttsc": "0.30.4",
|
|
52
53
|
"typescript": "7.0.2",
|
|
53
|
-
"vitest": "^4.0.0"
|
|
54
|
+
"vitest": "^4.0.0",
|
|
55
|
+
"@mpgd/game-runtime": "0.3.0"
|
|
54
56
|
},
|
|
55
57
|
"main": "./dist/index.js",
|
|
56
58
|
"types": "./dist/index.d.ts",
|