@ait-kit/sdk 0.3.0 → 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/README.md +110 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/platform-loader.d.ts +16 -0
- package/dist/platform-loader.d.ts.map +1 -0
- package/dist/platform-loader.js +35 -0
- package/dist/promotion/adapter.d.ts +3 -0
- package/dist/promotion/adapter.d.ts.map +1 -0
- package/dist/promotion/adapter.js +128 -0
- package/dist/promotion/platform-contract.d.ts +37 -0
- package/dist/promotion/platform-contract.d.ts.map +1 -0
- package/dist/promotion/platform-contract.js +1 -0
- package/dist/review/adapter.d.ts +3 -0
- package/dist/review/adapter.d.ts.map +1 -0
- package/dist/review/adapter.js +33 -0
- package/dist/review/platform-contract.d.ts +21 -0
- package/dist/review/platform-contract.d.ts.map +1 -0
- package/dist/review/platform-contract.js +1 -0
- package/dist/rn/ads.d.ts.map +1 -1
- package/dist/rn/ads.js +2 -7
- package/dist/rn/framework-loader.d.ts.map +1 -1
- package/dist/rn/framework-loader.js +6 -17
- package/dist/rn/iap.d.ts.map +1 -1
- package/dist/rn/iap.js +9 -28
- package/dist/rn/identity.d.ts.map +1 -1
- package/dist/rn/identity.js +4 -21
- package/dist/rn/index.d.ts +2 -0
- package/dist/rn/index.d.ts.map +1 -1
- package/dist/rn/index.js +2 -0
- package/dist/rn/notify-share.d.ts.map +1 -1
- package/dist/rn/notify-share.js +6 -48
- package/dist/rn/official-module.d.ts +16 -0
- package/dist/rn/official-module.d.ts.map +1 -1
- package/dist/rn/official-module.js +20 -0
- package/dist/rn/platform-loader.d.ts +4 -0
- package/dist/rn/platform-loader.d.ts.map +1 -0
- package/dist/rn/platform-loader.js +5 -0
- package/dist/rn/promotion.d.ts +9 -0
- package/dist/rn/promotion.d.ts.map +1 -0
- package/dist/rn/promotion.js +11 -0
- package/dist/rn/review.d.ts +7 -0
- package/dist/rn/review.d.ts.map +1 -0
- package/dist/rn/review.js +10 -0
- package/dist/rn/storage.d.ts.map +1 -1
- package/dist/rn/storage.js +4 -24
- package/dist/web/framework-loader.d.ts.map +1 -1
- package/dist/web/framework-loader.js +7 -23
- package/dist/web/identity.d.ts.map +1 -1
- package/dist/web/identity.js +6 -50
- package/dist/web/index.d.ts +2 -0
- package/dist/web/index.d.ts.map +1 -1
- package/dist/web/index.js +4 -5
- package/dist/web/notify-share.d.ts.map +1 -1
- package/dist/web/notify-share.js +6 -50
- package/dist/web/platform-loader.d.ts +4 -0
- package/dist/web/platform-loader.d.ts.map +1 -0
- package/dist/web/platform-loader.js +5 -0
- package/dist/web/promotion.d.ts +9 -0
- package/dist/web/promotion.d.ts.map +1 -0
- package/dist/web/promotion.js +10 -0
- package/dist/web/review.d.ts +7 -0
- package/dist/web/review.d.ts.map +1 -0
- package/dist/web/review.js +9 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -293,3 +293,113 @@ resolving `undefined` (installed app below the feature's minimum version)
|
|
|
293
293
|
now rejects with `SdkError("UNSUPPORTED")` instead of
|
|
294
294
|
`INVALID_ANONYMOUS_KEY`; the `"ERROR"` sentinel still rejects with
|
|
295
295
|
`INVALID_ANONYMOUS_KEY`.
|
|
296
|
+
|
|
297
|
+
## Review requests
|
|
298
|
+
|
|
299
|
+
```ts
|
|
300
|
+
import { createReactNativeReview } from "@ait-kit/sdk/rn";
|
|
301
|
+
// Web: import { createWebReview } from "@ait-kit/sdk/web";
|
|
302
|
+
const review = createReactNativeReview(); // share one instance across screens
|
|
303
|
+
if (await review.isSupported()) await review.request();
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
`ReviewAdapter` is a runtime-neutral root type. Factories accept `framework`
|
|
307
|
+
(shared `Review.request` contract or async loader), like the existing adapters.
|
|
308
|
+
RN translates the official `requestReview()` export; Web calls `Review.request()`.
|
|
309
|
+
The official SDK loads only on use. Missing features/support checkers return
|
|
310
|
+
`false`; import failure throws `SDK_UNAVAILABLE`; support-check exceptions propagate.
|
|
311
|
+
`request()` rechecks support and throws `UNSUPPORTED` when unavailable.
|
|
312
|
+
Concurrent requests on one instance share one Promise, cleared after success or
|
|
313
|
+
failure. There is no retry or timeout.
|
|
314
|
+
|
|
315
|
+
`Promise<void>` completion does not establish whether UI appeared or a review
|
|
316
|
+
was written. Never grant rewards, unlock features, or block navigation on review
|
|
317
|
+
completion. Complete and persist the core action first, then start a separately
|
|
318
|
+
error-handled review request without awaiting it in the core flow. The consumer
|
|
319
|
+
owns request timing, session limits, cooldowns and storage. Do not log raw SDK
|
|
320
|
+
errors by default.
|
|
321
|
+
|
|
322
|
+
Official reference: [Review.request](https://developers-apps-in-toss.toss.im/documentation/sdk/domains-api/review/review.request.md)
|
|
323
|
+
(Android/iOS Toss 5.253.0+, checked by the SDK). Verified package surfaces:
|
|
324
|
+
RN 2.10.10 and Web 3.4.0. Device UI behavior requires separate manual verification;
|
|
325
|
+
unit/tarball tests use injected SDKs or a stubbed native bridge.
|
|
326
|
+
|
|
327
|
+
## Explicit direct promotion rewards
|
|
328
|
+
|
|
329
|
+
```ts
|
|
330
|
+
import { createReactNativePromotion } from "@ait-kit/sdk/rn";
|
|
331
|
+
// Web: import { createWebPromotion } from "@ait-kit/sdk/web";
|
|
332
|
+
const promotion = createReactNativePromotion({ timeoutMs: 15_000 });
|
|
333
|
+
const support = await promotion.getSupport();
|
|
334
|
+
// RN 2.10.10 exposes no support checker: support is "unknown", not "supported".
|
|
335
|
+
// Opt into direct grants explicitly, with app-specific eligibility/budget checks.
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
`PromotionAdapter`, `PromotionSupport`, `PromotionGrantInput` and
|
|
339
|
+
`PromotionGrantResult` are runtime-neutral root types. Both factories accept
|
|
340
|
+
`framework` (shared `Promotion.grantReward` contract or async loader).
|
|
341
|
+
RN calls `grantPromotionReward({ params: { promotionCode, amount } })`;
|
|
342
|
+
Web calls only `Promotion.grantReward({ promotionCode, amount })`.
|
|
343
|
+
There is no legacy Web fallback or fallback to/from server payment flows.
|
|
344
|
+
|
|
345
|
+
`getSupport()` reports `unsupported` for missing functions or an explicit false
|
|
346
|
+
check, `supported` for a true check, and `unknown` when a function has no checker.
|
|
347
|
+
Import failures throw `SDK_UNAVAILABLE`; support-check exceptions propagate.
|
|
348
|
+
Every grant rechecks support. RN's documented `undefined` and the provider's
|
|
349
|
+
`UNSUPPORTED_APP_VERSION` throw `UNSUPPORTED`; malformed Web responses stay unknown.
|
|
350
|
+
|
|
351
|
+
Input errors throw `INVALID_PROMOTION_INPUT` before loading/calling the SDK:
|
|
352
|
+
`promotionCode` must be non-empty without surrounding whitespace (never trimmed
|
|
353
|
+
into a different code), and `amount` must be a positive safe integer. Campaign
|
|
354
|
+
eligibility, maximum amounts and budgets remain the consumer's responsibility.
|
|
355
|
+
|
|
356
|
+
Results:
|
|
357
|
+
|
|
358
|
+
- `granted` has a non-empty `rewardKey` and means only that the SDK reported success.
|
|
359
|
+
- `rejected` carries an explicit documented refusal code: `4100`, `4104`, `4105`,
|
|
360
|
+
`4108`, `4109`, `4110`, `4112`, or `4114`.
|
|
361
|
+
- `unknown` means confirmation is required: SDK exceptions/sentinels, malformed or
|
|
362
|
+
contradictory responses, deadlines, `UNKNOWN_ERROR`, `4113`, or new provider
|
|
363
|
+
codes. `4113` never becomes an inferred already-granted ledger state.
|
|
364
|
+
|
|
365
|
+
Provider messages and raw errors are not included in grant results. Provider codes
|
|
366
|
+
are retained only as bounded uppercase alphanumeric/underscore tokens; do not log
|
|
367
|
+
reward keys, promotion codes or whole SDK responses.
|
|
368
|
+
|
|
369
|
+
Share one adapter instance. A concurrent grant throws `PROMOTION_IN_PROGRESS`;
|
|
370
|
+
completed results are never cached as idempotent payments. `timeoutMs` defaults to
|
|
371
|
+
0 (disabled), accepts integers through 2147483647, and covers loading and the SDK
|
|
372
|
+
call. Elapsed time is checked before dispatch and when the SDK settles, so delayed
|
|
373
|
+
timer callbacks cannot start an overdue payment or turn a late result into success.
|
|
374
|
+
After timeout the result is unknown, but the instance stays locked until the
|
|
375
|
+
actual operation settles. A loader finishing after timeout never starts payment.
|
|
376
|
+
A late success/failure cannot change the returned timeout result. There is no
|
|
377
|
+
cancellation, automatic retry, or protection across instances/devices/restarts.
|
|
378
|
+
|
|
379
|
+
Consumer UI pattern (all callbacks are supplied by the app):
|
|
380
|
+
|
|
381
|
+
```ts
|
|
382
|
+
async function grantOnce(input, ui) {
|
|
383
|
+
ui.disableGrantAction();
|
|
384
|
+
try {
|
|
385
|
+
const result = await promotion.grantReward(input);
|
|
386
|
+
if (result.status === "unknown") {
|
|
387
|
+
ui.showConfirmationRequired(); // keep disabled; never retry automatically
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
ui.showSdkResult(result); // client report only; not a server ledger receipt
|
|
391
|
+
} catch {
|
|
392
|
+
ui.showConfirmationRequired(); // do not dump raw exceptions or auto-reenable
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Posting a client result to a server is not independent payment verification.
|
|
398
|
+
Consumers requiring a server ledger must keep their existing three-stage server
|
|
399
|
+
payment path. This API does not require client-side mTLS certificates/proxy tokens
|
|
400
|
+
and does not replace TrailBase claims or owned-currency accounting.
|
|
401
|
+
|
|
402
|
+
Official reference: [Promotion.grantReward](https://developers-apps-in-toss.toss.im/documentation/sdk/domains-api/promotion/promotion.grantreward.md).
|
|
403
|
+
Contracts are checked against RN 2.10.10 and Web 3.4.0 published types/code with
|
|
404
|
+
synthetic bridge fixtures. Device checks and official test-promotion calls remain
|
|
405
|
+
manual; no real promotion is invoked by tests.
|
package/dist/index.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ export type AdShowResult = {
|
|
|
28
28
|
reason?: string;
|
|
29
29
|
};
|
|
30
30
|
/** Stable error codes for SDK adapter failures. */
|
|
31
|
-
export type SdkErrorCode = "SDK_UNAVAILABLE" | "UNSUPPORTED" | "AD_NOT_LOADED" | "AD_ALREADY_SHOWING" | "AD_LOAD_FAILED" | "AD_LOAD_TIMEOUT" | "INVALID_LOGIN_RESULT" | "INVALID_ANONYMOUS_KEY" | "INVALID_SHARE_PATH";
|
|
31
|
+
export type SdkErrorCode = "SDK_UNAVAILABLE" | "UNSUPPORTED" | "AD_NOT_LOADED" | "AD_ALREADY_SHOWING" | "AD_LOAD_FAILED" | "AD_LOAD_TIMEOUT" | "INVALID_LOGIN_RESULT" | "INVALID_ANONYMOUS_KEY" | "INVALID_PROMOTION_INPUT" | "PROMOTION_IN_PROGRESS" | "INVALID_SHARE_PATH";
|
|
32
32
|
/** Terminal agreement outcomes delivered by the platform event. */
|
|
33
33
|
export type SdkNotificationAgreementType = "newAgreement" | "alreadyAgreed" | "agreementRejected";
|
|
34
34
|
/**
|
|
@@ -214,4 +214,6 @@ export declare class SdkError extends Error {
|
|
|
214
214
|
cause?: unknown;
|
|
215
215
|
});
|
|
216
216
|
}
|
|
217
|
+
export type { ReviewAdapter } from "./review/platform-contract.js";
|
|
218
|
+
export type { PromotionAdapter, PromotionSupport, PromotionGrantInput, PromotionGrantResult } from "./promotion/platform-contract.js";
|
|
217
219
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Internal runtime-neutral loader primitives; no official SDK is imported here. */
|
|
2
|
+
export type PlatformLoadResult<T> = {
|
|
3
|
+
available: true;
|
|
4
|
+
module: T;
|
|
5
|
+
} | {
|
|
6
|
+
available: false;
|
|
7
|
+
reason: string;
|
|
8
|
+
};
|
|
9
|
+
export type PlatformLoader<T> = () => Promise<PlatformLoadResult<T>>;
|
|
10
|
+
/** Preserve injected loaders verbatim and construct defaults only when needed. */
|
|
11
|
+
export declare function resolvePlatformLoader<T>(framework: T | PlatformLoader<T> | undefined, createDefault: () => PlatformLoader<T>): PlatformLoader<T>;
|
|
12
|
+
/** Cache only successful selections; unavailable results and thrown loads retry. */
|
|
13
|
+
export declare function createCachedPlatformLoader<T>(load: PlatformLoader<T>, errorReason: (error: unknown) => string): PlatformLoader<T>;
|
|
14
|
+
/** Preserve existing diagnostic detail policies chosen by each adapter. */
|
|
15
|
+
export declare function frameworkImportError(packageName: string, error: unknown, includeDetails: boolean): string;
|
|
16
|
+
//# sourceMappingURL=platform-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-loader.d.ts","sourceRoot":"","sources":["../src/platform-loader.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAC5B;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,CAAC,CAAA;CAAE,GAC9B;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AACzC,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;AAErE,kFAAkF;AAClF,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,SAAS,EAAE,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS,EAC5C,aAAa,EAAE,MAAM,cAAc,CAAC,CAAC,CAAC,GACrC,cAAc,CAAC,CAAC,CAAC,CAInB;AAED,oFAAoF;AACpF,wBAAgB,0BAA0B,CAAC,CAAC,EAC1C,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,EACvB,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,GACtC,cAAc,CAAC,CAAC,CAAC,CAcnB;AAED,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,GAAG,MAAM,CAKzG"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Preserve injected loaders verbatim and construct defaults only when needed. */
|
|
2
|
+
export function resolvePlatformLoader(framework, createDefault) {
|
|
3
|
+
if (!framework)
|
|
4
|
+
return createDefault();
|
|
5
|
+
if (typeof framework === "function")
|
|
6
|
+
return framework;
|
|
7
|
+
return async () => ({ available: true, module: framework });
|
|
8
|
+
}
|
|
9
|
+
/** Cache only successful selections; unavailable results and thrown loads retry. */
|
|
10
|
+
export function createCachedPlatformLoader(load, errorReason) {
|
|
11
|
+
let cached;
|
|
12
|
+
return async () => {
|
|
13
|
+
if (cached)
|
|
14
|
+
return { available: true, module: cached.module };
|
|
15
|
+
try {
|
|
16
|
+
const result = await load();
|
|
17
|
+
// Keep the cache independent from the mutable result envelope returned
|
|
18
|
+
// to callers, as the original per-adapter loaders did.
|
|
19
|
+
if (result.available)
|
|
20
|
+
cached = { available: true, module: result.module };
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
return { available: false, reason: errorReason(error) };
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/** Preserve existing diagnostic detail policies chosen by each adapter. */
|
|
29
|
+
export function frameworkImportError(packageName, error, includeDetails) {
|
|
30
|
+
const prefix = `failed to import ${packageName}`;
|
|
31
|
+
if (!includeDetails)
|
|
32
|
+
return prefix;
|
|
33
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
34
|
+
return `${prefix}: ${message}`;
|
|
35
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/promotion/adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACxB,MAAM,wBAAwB,CAAC;AAiDhC,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,uBAAuB,EAAE,SAAS,SAAI,GAAG,gBAAgB,CA+DvG"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { SdkError } from "../index.js";
|
|
2
|
+
// Official Promotion.grantReward documentation (RN 2.10.10 / Web 3.4.0).
|
|
3
|
+
// 4113 is intentionally absent: it cannot establish this attempt's outcome.
|
|
4
|
+
const REJECTION_CODES = new Set(["4100", "4104", "4105", "4108", "4109", "4110", "4112", "4114"]);
|
|
5
|
+
function unknown(reason, providerCode) {
|
|
6
|
+
return providerCode === undefined ? { status: "unknown", reason } : { status: "unknown", reason, providerCode };
|
|
7
|
+
}
|
|
8
|
+
function normalize(value, thrown) {
|
|
9
|
+
if (typeof value !== "object" || value === null) {
|
|
10
|
+
return unknown(thrown || value === "ERROR" ? "sdk_error" : "invalid_response");
|
|
11
|
+
}
|
|
12
|
+
const data = value;
|
|
13
|
+
const rawCode = data.errorCode ?? data.code;
|
|
14
|
+
const code = typeof rawCode === "string" && /^[A-Z0-9_]{1,64}$/.test(rawCode) ? rawCode : undefined;
|
|
15
|
+
const hasError = "errorCode" in data || "code" in data || "error" in data || "message" in data;
|
|
16
|
+
if (("key" in data && (thrown || hasError)) ||
|
|
17
|
+
(data.code !== undefined && data.errorCode !== undefined && data.code !== data.errorCode)) {
|
|
18
|
+
return unknown("invalid_response", code);
|
|
19
|
+
}
|
|
20
|
+
if (!thrown && typeof data.key === "string" && data.key.trim().length > 0) {
|
|
21
|
+
return { status: "granted", rewardKey: data.key };
|
|
22
|
+
}
|
|
23
|
+
if ("key" in data)
|
|
24
|
+
return unknown("invalid_response", code);
|
|
25
|
+
if (code === "UNSUPPORTED_APP_VERSION") {
|
|
26
|
+
throw new SdkError("UNSUPPORTED", "direct promotion rewards are not supported on this app version");
|
|
27
|
+
}
|
|
28
|
+
if (code && REJECTION_CODES.has(code))
|
|
29
|
+
return { status: "rejected", providerCode: code };
|
|
30
|
+
return unknown(code ? "ambiguous_provider_error" : thrown ? "sdk_error" : "invalid_response", code);
|
|
31
|
+
}
|
|
32
|
+
function support(platform) {
|
|
33
|
+
const grant = platform.Promotion?.grantReward;
|
|
34
|
+
if (typeof grant !== "function")
|
|
35
|
+
return "unsupported";
|
|
36
|
+
if (typeof grant.isSupported !== "function")
|
|
37
|
+
return "unknown";
|
|
38
|
+
return grant.isSupported() ? "supported" : "unsupported";
|
|
39
|
+
}
|
|
40
|
+
function validate(input) {
|
|
41
|
+
if (!input || typeof input.promotionCode !== "string" || !input.promotionCode.trim() ||
|
|
42
|
+
input.promotionCode !== input.promotionCode.trim() || !Number.isSafeInteger(input.amount) || input.amount <= 0) {
|
|
43
|
+
throw new SdkError("INVALID_PROMOTION_INPUT", "promotionCode must be non-empty without surrounding whitespace and amount must be a positive safe integer");
|
|
44
|
+
}
|
|
45
|
+
// Snapshot before loading; callers cannot change the pending payment input.
|
|
46
|
+
return { promotionCode: input.promotionCode, amount: input.amount };
|
|
47
|
+
}
|
|
48
|
+
export function createPromotionAdapter(loader, timeoutMs = 0) {
|
|
49
|
+
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 0 || timeoutMs > 2_147_483_647) {
|
|
50
|
+
throw new SdkError("INVALID_PROMOTION_INPUT", "timeoutMs must be an integer from 0 to 2147483647");
|
|
51
|
+
}
|
|
52
|
+
let inFlight = false;
|
|
53
|
+
const load = async () => {
|
|
54
|
+
const result = await loader();
|
|
55
|
+
if (!result.available)
|
|
56
|
+
throw new SdkError("SDK_UNAVAILABLE", result.reason);
|
|
57
|
+
return result.module;
|
|
58
|
+
};
|
|
59
|
+
return {
|
|
60
|
+
async getSupport() { return support(await load()); },
|
|
61
|
+
grantReward(input) {
|
|
62
|
+
let validated;
|
|
63
|
+
try {
|
|
64
|
+
validated = validate(input);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
return Promise.reject(error);
|
|
68
|
+
}
|
|
69
|
+
if (inFlight)
|
|
70
|
+
return Promise.reject(new SdkError("PROMOTION_IN_PROGRESS", "a direct promotion request is still in progress"));
|
|
71
|
+
inFlight = true;
|
|
72
|
+
const now = typeof performance !== "undefined" && typeof performance.now === "function"
|
|
73
|
+
? performance.now.bind(performance)
|
|
74
|
+
: Date.now;
|
|
75
|
+
const startedAt = now();
|
|
76
|
+
let expired = false;
|
|
77
|
+
// Timers cannot run while JS is blocked or draining microtasks. Check the
|
|
78
|
+
// elapsed budget too, using one clock source for the entire request.
|
|
79
|
+
const hasExpired = () => expired || (timeoutMs > 0 && now() - startedAt >= timeoutMs);
|
|
80
|
+
let timer;
|
|
81
|
+
const work = Promise.resolve().then(async () => {
|
|
82
|
+
if (hasExpired())
|
|
83
|
+
return unknown("timeout");
|
|
84
|
+
const platform = await load();
|
|
85
|
+
// A loading timeout must not launch a new payment later.
|
|
86
|
+
if (hasExpired())
|
|
87
|
+
return unknown("timeout");
|
|
88
|
+
const availability = support(platform);
|
|
89
|
+
if (hasExpired())
|
|
90
|
+
return unknown("timeout");
|
|
91
|
+
if (availability === "unsupported") {
|
|
92
|
+
throw new SdkError("UNSUPPORTED", "the installed SDK or app does not support direct promotion rewards");
|
|
93
|
+
}
|
|
94
|
+
let response;
|
|
95
|
+
try {
|
|
96
|
+
response = await platform.Promotion.grantReward(validated);
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
if (hasExpired())
|
|
100
|
+
return unknown("timeout");
|
|
101
|
+
// The RN conversion uses this only for the documented undefined result.
|
|
102
|
+
if (error instanceof SdkError && error.code === "UNSUPPORTED")
|
|
103
|
+
throw error;
|
|
104
|
+
return normalize(error, true);
|
|
105
|
+
}
|
|
106
|
+
if (hasExpired())
|
|
107
|
+
return unknown("timeout");
|
|
108
|
+
return normalize(response, false);
|
|
109
|
+
}).catch((error) => {
|
|
110
|
+
// A delayed loader/support failure must not beat an elapsed deadline.
|
|
111
|
+
if (hasExpired())
|
|
112
|
+
return unknown("timeout");
|
|
113
|
+
throw error;
|
|
114
|
+
}).finally(() => {
|
|
115
|
+
inFlight = false;
|
|
116
|
+
if (timer !== undefined)
|
|
117
|
+
clearTimeout(timer);
|
|
118
|
+
});
|
|
119
|
+
if (timeoutMs === 0)
|
|
120
|
+
return work;
|
|
121
|
+
const deadline = new Promise(resolve => {
|
|
122
|
+
timer = setTimeout(() => { expired = true; resolve(unknown("timeout")); }, timeoutMs);
|
|
123
|
+
});
|
|
124
|
+
// Only actual SDK/load settlement releases the lock, not this race.
|
|
125
|
+
return Promise.race([work, deadline]);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type PromotionSupport = "supported" | "unsupported" | "unknown";
|
|
2
|
+
export interface PromotionGrantInput {
|
|
3
|
+
promotionCode: string;
|
|
4
|
+
amount: number;
|
|
5
|
+
}
|
|
6
|
+
export type PromotionGrantResult = {
|
|
7
|
+
status: "granted";
|
|
8
|
+
rewardKey: string;
|
|
9
|
+
} | {
|
|
10
|
+
status: "rejected";
|
|
11
|
+
providerCode: string;
|
|
12
|
+
} | {
|
|
13
|
+
status: "unknown";
|
|
14
|
+
reason: "sdk_error" | "timeout" | "invalid_response" | "ambiguous_provider_error";
|
|
15
|
+
providerCode?: string;
|
|
16
|
+
};
|
|
17
|
+
/** Client SDK reports are not independently verified server ledger evidence. */
|
|
18
|
+
export interface PromotionAdapter {
|
|
19
|
+
getSupport(): Promise<PromotionSupport>;
|
|
20
|
+
grantReward(input: PromotionGrantInput): Promise<PromotionGrantResult>;
|
|
21
|
+
}
|
|
22
|
+
/** Injected results are untrusted, just like the native bridge response. */
|
|
23
|
+
export interface PromotionPlatformSdk {
|
|
24
|
+
Promotion?: {
|
|
25
|
+
grantReward?: ((input: PromotionGrantInput) => Promise<unknown>) & {
|
|
26
|
+
isSupported?: () => boolean;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export type PromotionPlatformLoader = () => Promise<{
|
|
31
|
+
available: true;
|
|
32
|
+
module: PromotionPlatformSdk;
|
|
33
|
+
} | {
|
|
34
|
+
available: false;
|
|
35
|
+
reason: string;
|
|
36
|
+
}>;
|
|
37
|
+
//# sourceMappingURL=platform-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-contract.d.ts","sourceRoot":"","sources":["../../src/promotion/platform-contract.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,aAAa,GAAG,SAAS,CAAC;AAEvE,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC5C;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,kBAAkB,GAAG,0BAA0B,CAAC;IAClF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEN,gFAAgF;AAChF,MAAM,WAAW,gBAAgB;IAC/B,UAAU,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACxC,WAAW,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACxE;AAED,4EAA4E;AAC5E,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE;QACV,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,mBAAmB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG;YACjE,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;SAC7B,CAAC;KACH,CAAC;CACH;AAED,MAAM,MAAM,uBAAuB,GAAG,MAAM,OAAO,CAC/C;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,GACjD;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CACvC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/review/adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAqB,MAAM,wBAAwB,CAAC;AAErG,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,oBAAoB,GAAG,aAAa,CA6B/E"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { SdkError } from "../index.js";
|
|
2
|
+
export function createReviewAdapter(loader) {
|
|
3
|
+
let inFlight;
|
|
4
|
+
const load = async () => {
|
|
5
|
+
const result = await loader();
|
|
6
|
+
if (!result.available)
|
|
7
|
+
throw new SdkError("SDK_UNAVAILABLE", result.reason);
|
|
8
|
+
return result.module;
|
|
9
|
+
};
|
|
10
|
+
const supported = (platform) => {
|
|
11
|
+
const request = platform.Review?.request;
|
|
12
|
+
return typeof request === "function" &&
|
|
13
|
+
typeof request.isSupported === "function" && request.isSupported() === true;
|
|
14
|
+
};
|
|
15
|
+
return {
|
|
16
|
+
async isSupported() {
|
|
17
|
+
return supported(await load());
|
|
18
|
+
},
|
|
19
|
+
request() {
|
|
20
|
+
if (inFlight)
|
|
21
|
+
return inFlight;
|
|
22
|
+
// Schedule loading after publishing the lock, including reentrant loaders.
|
|
23
|
+
inFlight = Promise.resolve().then(async () => {
|
|
24
|
+
const platform = await load();
|
|
25
|
+
if (!supported(platform)) {
|
|
26
|
+
throw new SdkError("UNSUPPORTED", "review requests are not supported on this app version");
|
|
27
|
+
}
|
|
28
|
+
await platform.Review.request();
|
|
29
|
+
}).finally(() => { inFlight = undefined; });
|
|
30
|
+
return inFlight;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Minimal injectable shape shared by the platform adapters. */
|
|
2
|
+
export interface ReviewPlatformSdk {
|
|
3
|
+
Review?: {
|
|
4
|
+
request?: (() => Promise<void>) & {
|
|
5
|
+
isSupported?: () => boolean;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export type ReviewPlatformLoader = () => Promise<{
|
|
10
|
+
available: true;
|
|
11
|
+
module: ReviewPlatformSdk;
|
|
12
|
+
} | {
|
|
13
|
+
available: false;
|
|
14
|
+
reason: string;
|
|
15
|
+
}>;
|
|
16
|
+
/** Completion only means the SDK call settled, never that a review was written. */
|
|
17
|
+
export interface ReviewAdapter {
|
|
18
|
+
isSupported(): Promise<boolean>;
|
|
19
|
+
request(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=platform-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-contract.d.ts","sourceRoot":"","sources":["../../src/review/platform-contract.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG;YAAE,WAAW,CAAC,EAAE,MAAM,OAAO,CAAA;SAAE,CAAC;KACnE,CAAC;CACH;AAED,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,CAC5C;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,GAC9C;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CACvC,CAAC;AAEF,mFAAmF;AACnF,MAAM,WAAW,aAAa;IAC5B,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/rn/ads.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ads.d.ts","sourceRoot":"","sources":["../../src/rn/ads.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ads.d.ts","sourceRoot":"","sources":["../../src/rn/ads.ts"],"names":[],"mappings":"AAIA,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEzE,OAAO,KAAK,EAAyB,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC1F,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AAE/B,wEAAwE;AACxE,MAAM,MAAM,SAAS,GAAG,YAAY,CAAC;AAErC,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,SAAS,CAAC,EAAE,eAAe,GAAG,mBAAmB,CAAC;IAClD,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD;;;;OAIG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC5D;AAmED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,qBAA0B,GAAG,cAAc,CAqKxF"}
|
package/dist/rn/ads.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolvePlatformLoader } from "../platform-loader.js";
|
|
1
2
|
// Relative import: the package ships per-file output (no bundling), so
|
|
2
3
|
// the /rn entry and the root entry share one SdkError constructor and
|
|
3
4
|
// `instanceof` holds for consumers importing either entry.
|
|
@@ -222,11 +223,5 @@ function errorMessage(error) {
|
|
|
222
223
|
return error instanceof Error ? error.message : String(error);
|
|
223
224
|
}
|
|
224
225
|
function normalizeLoader(framework) {
|
|
225
|
-
|
|
226
|
-
return createDefaultFrameworkLoader();
|
|
227
|
-
}
|
|
228
|
-
if (typeof framework === "function") {
|
|
229
|
-
return framework;
|
|
230
|
-
}
|
|
231
|
-
return async () => ({ available: true, module: framework });
|
|
226
|
+
return resolvePlatformLoader(framework, createDefaultFrameworkLoader);
|
|
232
227
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"framework-loader.d.ts","sourceRoot":"","sources":["../../src/rn/framework-loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"framework-loader.d.ts","sourceRoot":"","sources":["../../src/rn/framework-loader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEnE;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,GAChD;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAEjE;;;;;GAKG;AACH,wBAAgB,4BAA4B,IAAI,eAAe,CAO9D"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createRnPlatformLoader } from "./platform-loader.js";
|
|
1
2
|
/**
|
|
2
3
|
* Default lazy loader: imports `@apps-in-toss/framework` only when an ad
|
|
3
4
|
* operation needs it. A failed import is never cached, so a later call
|
|
@@ -5,22 +6,10 @@
|
|
|
5
6
|
* successful loads are cached.
|
|
6
7
|
*/
|
|
7
8
|
export function createDefaultFrameworkLoader() {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return { available: true, module: cached };
|
|
9
|
+
return createRnPlatformLoader((module) => {
|
|
10
|
+
if (typeof module.loadFullScreenAd !== "function" || typeof module.showFullScreenAd !== "function") {
|
|
11
|
+
return { available: false, reason: "@apps-in-toss/framework does not expose the Ads APIs" };
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (typeof module.loadFullScreenAd !== "function" || typeof module.showFullScreenAd !== "function") {
|
|
16
|
-
return { available: false, reason: "@apps-in-toss/framework does not expose the Ads APIs" };
|
|
17
|
-
}
|
|
18
|
-
cached = module;
|
|
19
|
-
return { available: true, module: cached };
|
|
20
|
-
}
|
|
21
|
-
catch (error) {
|
|
22
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
23
|
-
return { available: false, reason: `failed to import @apps-in-toss/framework: ${message}` };
|
|
24
|
-
}
|
|
25
|
-
};
|
|
13
|
+
return { available: true, module: module };
|
|
14
|
+
});
|
|
26
15
|
}
|
package/dist/rn/iap.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iap.d.ts","sourceRoot":"","sources":["../../src/rn/iap.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"iap.d.ts","sourceRoot":"","sources":["../../src/rn/iap.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACrG,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAE5F;;;;GAIG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC;IAC9E;;;;OAIG;IACH,SAAS,CAAC,EAAE,qBAAqB,GAAG,iBAAiB,CAAC;CACvD;AAED,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACrE,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAElC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,0CAGlE"}
|
package/dist/rn/iap.js
CHANGED
|
@@ -1,35 +1,16 @@
|
|
|
1
|
+
import { resolvePlatformLoader } from "../platform-loader.js";
|
|
2
|
+
import { createRnPlatformLoader } from "./platform-loader.js";
|
|
1
3
|
import { createIapAdapter } from "../iap/adapter.js";
|
|
2
4
|
export function createReactNativeIap(options) {
|
|
3
|
-
const loader =
|
|
4
|
-
? createDefaultRnIapLoader()
|
|
5
|
-
: typeof options.framework === "function"
|
|
6
|
-
? options.framework
|
|
7
|
-
: async () => ({ available: true, module: options.framework });
|
|
5
|
+
const loader = resolvePlatformLoader(options.framework, createDefaultRnIapLoader);
|
|
8
6
|
return createIapAdapter({ ...options, loader });
|
|
9
7
|
}
|
|
10
8
|
function createDefaultRnIapLoader() {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (
|
|
14
|
-
return { available:
|
|
9
|
+
return createRnPlatformLoader((framework) => {
|
|
10
|
+
const iap = framework.IAP;
|
|
11
|
+
if (typeof iap !== "object" || iap === null) {
|
|
12
|
+
return { available: false, reason: "@apps-in-toss/framework does not expose an IAP domain" };
|
|
15
13
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const iap = framework.IAP;
|
|
19
|
-
if (typeof iap !== "object" || iap === null) {
|
|
20
|
-
return {
|
|
21
|
-
available: false,
|
|
22
|
-
reason: "@apps-in-toss/framework does not expose an IAP domain"
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
// Per-operation capability is validated at each call site: an
|
|
26
|
-
// installed version may expose some IAP functions but not others.
|
|
27
|
-
cached = iap;
|
|
28
|
-
return { available: true, module: cached };
|
|
29
|
-
}
|
|
30
|
-
catch (error) {
|
|
31
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
32
|
-
return { available: false, reason: `failed to import @apps-in-toss/framework: ${message}` };
|
|
33
|
-
}
|
|
34
|
-
};
|
|
14
|
+
return { available: true, module: iap };
|
|
15
|
+
});
|
|
35
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/rn/identity.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/rn/identity.ts"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EAGzB,MAAM,kCAAkC,CAAC;AAG1C,MAAM,WAAW,0BAA0B;IACzC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,mBAAmB,GAAG,sBAAsB,CAAC;CAC1D;AAED,MAAM,WAAW,mBAAmB;IAClC,oEAAoE;IACpE,KAAK,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IACjC,mEAAmE;IACnE,eAAe,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7C;AAED,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,0BAA+B,GAAG,mBAAmB,CAavG;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,0BAA0B,CAAC,WAAW,CAAC,GACjD,sBAAsB,CAExB"}
|
package/dist/rn/identity.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { resolvePlatformLoader } from "../platform-loader.js";
|
|
2
|
+
import { createRnPlatformLoader } from "./platform-loader.js";
|
|
1
3
|
import { SdkError } from "../index.js";
|
|
2
4
|
import { runSdkGetAnonymousKey, runSdkLogin } from "../identity/platform-contract.js";
|
|
3
5
|
import { adaptOfficialRnIdentity } from "./official-module.js";
|
|
@@ -16,13 +18,7 @@ export function createReactNativeIdentity(options = {}) {
|
|
|
16
18
|
};
|
|
17
19
|
}
|
|
18
20
|
export function normalizeIdentityLoader(framework) {
|
|
19
|
-
|
|
20
|
-
return createDefaultRnIdentityLoader();
|
|
21
|
-
}
|
|
22
|
-
if (typeof framework === "function") {
|
|
23
|
-
return framework;
|
|
24
|
-
}
|
|
25
|
-
return async () => ({ available: true, module: framework });
|
|
21
|
+
return resolvePlatformLoader(framework, createDefaultRnIdentityLoader);
|
|
26
22
|
}
|
|
27
23
|
/**
|
|
28
24
|
* Default loader: imports the official `@apps-in-toss/framework` lazily and
|
|
@@ -31,18 +27,5 @@ export function normalizeIdentityLoader(framework) {
|
|
|
31
27
|
* retries); successful loads cache the converted module.
|
|
32
28
|
*/
|
|
33
29
|
function createDefaultRnIdentityLoader() {
|
|
34
|
-
|
|
35
|
-
return async () => {
|
|
36
|
-
if (cached) {
|
|
37
|
-
return { available: true, module: cached };
|
|
38
|
-
}
|
|
39
|
-
try {
|
|
40
|
-
cached = adaptOfficialRnIdentity(await import("@apps-in-toss/framework"));
|
|
41
|
-
return { available: true, module: cached };
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
45
|
-
return { available: false, reason: `failed to import @apps-in-toss/framework: ${message}` };
|
|
46
|
-
}
|
|
47
|
-
};
|
|
30
|
+
return createRnPlatformLoader(module => ({ available: true, module: adaptOfficialRnIdentity(module) }));
|
|
48
31
|
}
|
package/dist/rn/index.d.ts
CHANGED
|
@@ -24,4 +24,6 @@ export { createReactNativeStorage, type ReactNativeStorageOptions } from "./stor
|
|
|
24
24
|
export { createReactNativeNotification, createReactNativeShare, type ReactNativeNotification, type ReactNativeNotificationOptions, type ReactNativeShare, type ReactNativeShareOptions } from "./notify-share.js";
|
|
25
25
|
export { createDefaultFrameworkLoader, type FrameworkLoader } from "./framework-loader.js";
|
|
26
26
|
export type { FullScreenAdShowEvent, FullScreenAdSupport, LoadFullScreenAdParams, ShowFullScreenAdParams } from "./framework-contract.js";
|
|
27
|
+
export { createReactNativeReview, type ReactNativeReviewOptions } from "./review.js";
|
|
28
|
+
export { createReactNativePromotion, type ReactNativePromotionOptions } from "./promotion.js";
|
|
27
29
|
//# sourceMappingURL=index.d.ts.map
|