@ait-kit/sdk 0.2.0 → 0.3.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 +68 -9
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/rn/ads.d.ts.map +1 -1
- package/dist/rn/ads.js +118 -112
- package/dist/rn/identity.d.ts.map +1 -1
- package/dist/rn/identity.js +8 -2
- package/dist/rn/notify-share.d.ts +3 -3
- package/dist/rn/notify-share.d.ts.map +1 -1
- package/dist/rn/notify-share.js +30 -5
- package/dist/rn/official-module.d.ts +67 -0
- package/dist/rn/official-module.d.ts.map +1 -0
- package/dist/rn/official-module.js +86 -0
- package/dist/rn/storage.js +3 -1
- package/dist/share/platform-contract.d.ts +4 -4
- package/dist/share/platform-contract.js +5 -5
- package/dist/web/identity.js +27 -4
- package/dist/web/notify-share.d.ts +3 -2
- package/dist/web/notify-share.d.ts.map +1 -1
- package/dist/web/notify-share.js +26 -4
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -99,7 +99,7 @@ SDK initialization never grants or completes pending orders by itself.
|
|
|
99
99
|
| Grant completion notify | ✅ | ✅ | sent only after server grant confirms |
|
|
100
100
|
| Full-screen ads | ✅ | ➖ | ads are RN-only today |
|
|
101
101
|
| Notification agreement | ✅ | ✅ | event-based, one template per request |
|
|
102
|
-
| Share link / share sheet | ✅ | ✅ | `intoss://` paths; `
|
|
102
|
+
| Share link / share sheet | ✅ | ✅ | `intoss://` paths; `completed` ≠ shared |
|
|
103
103
|
| Unsupported app version | `SdkError("UNSUPPORTED")` | same | per-function `isSupported` gates |
|
|
104
104
|
|
|
105
105
|
Notification and sharing adapters ship in both entries (see below).
|
|
@@ -136,8 +136,13 @@ Contracts:
|
|
|
136
136
|
reject with `SdkError("INVALID_LOGIN_RESULT")`; unsupported environments
|
|
137
137
|
with `UNSUPPORTED`; SDK rejections propagate unchanged.
|
|
138
138
|
- **Anonymous key** results must be the documented `{ type: "HASH", hash }`
|
|
139
|
-
shape. Anything else (including
|
|
140
|
-
`SdkError("INVALID_ANONYMOUS_KEY")` — the adapter never
|
|
139
|
+
shape. Anything else (including the official SDK's `"ERROR"` sentinel)
|
|
140
|
+
rejects with `SdkError("INVALID_ANONYMOUS_KEY")` — the adapter never
|
|
141
|
+
invents a key. One exception: on React Native the official
|
|
142
|
+
`getAnonymousKey()` resolves `undefined` when the installed app is below
|
|
143
|
+
the feature's minimum version, which rejects with
|
|
144
|
+
`SdkError("UNSUPPORTED")` instead — an unsupported environment, not a
|
|
145
|
+
malformed key.
|
|
141
146
|
- **Storage** keys and string values pass through byte-for-byte: no
|
|
142
147
|
namespace prefixing, no key transformation. Compose namespaced keys
|
|
143
148
|
yourself (e.g. `cart:items`). `get` resolves `null` for missing keys;
|
|
@@ -171,10 +176,10 @@ const result = await notification.requestAgreement("TEMPLATE_CODE");
|
|
|
171
176
|
const share = createReactNativeShare();
|
|
172
177
|
const link = await share.createLink("intoss://my-app/about", "https://cdn/og.png");
|
|
173
178
|
|
|
174
|
-
// 3. Share sheet: "
|
|
179
|
+
// 3. Share sheet: "completed" means the SDK share call finished — nothing more.
|
|
175
180
|
const uiResult = await share.sendMessage(`check this out ${link}`);
|
|
176
|
-
// uiResult.status: "
|
|
177
|
-
// shared and never grants share-reward eligibility.
|
|
181
|
+
// uiResult.status: "completed" | "failed" — completed does NOT prove the
|
|
182
|
+
// user shared and never grants share-reward eligibility.
|
|
178
183
|
```
|
|
179
184
|
|
|
180
185
|
Contracts:
|
|
@@ -186,8 +191,10 @@ Contracts:
|
|
|
186
191
|
- **Share links** validate the documented `intoss://` path contract
|
|
187
192
|
(`INVALID_SHARE_PATH` otherwise) and pass the resolved link through
|
|
188
193
|
verbatim. OG image generation is the consumer's concern.
|
|
189
|
-
- **Share sheet** resolution is `
|
|
190
|
-
|
|
194
|
+
- **Share sheet** resolution is `completed`, meaning ONLY that the SDK share
|
|
195
|
+
call finished — the underlying SDKs do not report whether the sheet opened,
|
|
196
|
+
closed, or the user actually shared. Reward grants and completion tracking
|
|
197
|
+
stay with the consumer. (Renamed from `closed` in 0.3.0; see Migrating.)
|
|
191
198
|
- Unsupported surfaces/app versions reject with `SdkError("UNSUPPORTED")`.
|
|
192
199
|
|
|
193
200
|
## React Native full-screen ads
|
|
@@ -216,7 +223,16 @@ Behavior:
|
|
|
216
223
|
are single-use: after a show flow ends (rewarded, dismissed, failed,
|
|
217
224
|
timeout), a fresh load is required.
|
|
218
225
|
- The whole show flow has one deadline (`showTimeoutMs`, default 60s);
|
|
219
|
-
`loadTimeoutMs` (default 30s) bounds loads.
|
|
226
|
+
`loadTimeoutMs` (default 30s) bounds loads. The deadline is a single
|
|
227
|
+
budget covering SDK loading AND the provider event flow: a loader that
|
|
228
|
+
consumes most of it leaves only the remainder for the event wait, and a
|
|
229
|
+
fully consumed budget never registers with the provider. Timeout results
|
|
230
|
+
come from the event flow's own deadline, so the subscription is cleaned
|
|
231
|
+
up before the timeout settles — no orphaned listener outlives the call.
|
|
232
|
+
- Slot updates land inside the returned promise's settlement: a failed
|
|
233
|
+
load frees its slot before the caller's `catch` resumes (an immediate
|
|
234
|
+
retry starts a fresh registration), and a successful load is promoted
|
|
235
|
+
before the caller's `await` resumes (an immediate show works).
|
|
220
236
|
- Missing or failed-to-import framework → `SdkError("SDK_UNAVAILABLE")`;
|
|
221
237
|
unsupported app versions → `SdkError("UNSUPPORTED")`. Load failures are
|
|
222
238
|
never permanently cached — a later call retries the import.
|
|
@@ -234,3 +250,46 @@ notification and sharing.)
|
|
|
234
250
|
|
|
235
251
|
`@ait-kit/sdk` is versioned independently from the server API packages
|
|
236
252
|
(`@ait-kit/api-*`), which release in lockstep with each other.
|
|
253
|
+
|
|
254
|
+
## Verified official SDK versions
|
|
255
|
+
|
|
256
|
+
The adapters are developed and continuously checked against these exact
|
|
257
|
+
official releases (see `scripts/test-package-tarballs.mjs`):
|
|
258
|
+
|
|
259
|
+
| Official package | Verified version | Peer range |
|
|
260
|
+
|---|---|---|
|
|
261
|
+
| `@apps-in-toss/framework` (RN) | 2.10.10 | `>=2.10.10` |
|
|
262
|
+
| `@apps-in-toss/web-framework` (Web) | 3.4.0 | `>=3.4.0` |
|
|
263
|
+
|
|
264
|
+
Older versions may work where the runtime surfaces match (every capability
|
|
265
|
+
is checked per function and missing ones reject with `UNSUPPORTED`), but
|
|
266
|
+
only the versions above are verified. Newer versions are expected to work
|
|
267
|
+
via the same structural checks; if an official export shape changes, the
|
|
268
|
+
per-operation errors surface it instead of silent misbehavior.
|
|
269
|
+
|
|
270
|
+
## Migrating
|
|
271
|
+
|
|
272
|
+
### 0.3.0 — share sheet result `closed` → `completed`
|
|
273
|
+
|
|
274
|
+
`sendMessage` now resolves `{ status: "completed" }` instead of
|
|
275
|
+
`{ status: "closed" }`. The meaning also got precise: `completed` states
|
|
276
|
+
only that the SDK share **call** finished. It does not prove the share
|
|
277
|
+
sheet opened or closed, that the user shared, or that any reward
|
|
278
|
+
eligibility was earned. Update any `status === "closed"` checks; failure
|
|
279
|
+
results (`status: "failed"` with `code`/`reason`) are unchanged.
|
|
280
|
+
|
|
281
|
+
### 0.3.0 — RN adapters call the official export shapes
|
|
282
|
+
|
|
283
|
+
The React Native default loaders now convert the official flat exports
|
|
284
|
+
(`appLogin`, `getAnonymousKey`, `requestNotificationAgreement`,
|
|
285
|
+
`getTossShareLink`, `share`) into the shared adapter contracts. Previously
|
|
286
|
+
a correctly installed official RN SDK still produced
|
|
287
|
+
`SdkError("UNSUPPORTED")` for these five capabilities because the loaders
|
|
288
|
+
looked for the web SDK's namespaced shapes. Custom `framework` injections
|
|
289
|
+
using the internal namespaced contract or a loader keep working unchanged.
|
|
290
|
+
|
|
291
|
+
One error-mapping change rides along: the official RN `getAnonymousKey()`
|
|
292
|
+
resolving `undefined` (installed app below the feature's minimum version)
|
|
293
|
+
now rejects with `SdkError("UNSUPPORTED")` instead of
|
|
294
|
+
`INVALID_ANONYMOUS_KEY`; the `"ERROR"` sentinel still rejects with
|
|
295
|
+
`INVALID_ANONYMOUS_KEY`.
|
package/dist/index.d.ts
CHANGED
|
@@ -62,12 +62,14 @@ export type SdkNotificationAgreementResult = {
|
|
|
62
62
|
reason?: string;
|
|
63
63
|
};
|
|
64
64
|
/**
|
|
65
|
-
* Result of opening the share UI. `
|
|
66
|
-
*
|
|
67
|
-
* never grants share-reward eligibility
|
|
65
|
+
* Result of opening the share UI. `completed` means ONLY that the SDK share
|
|
66
|
+
* call finished — it does NOT prove the share sheet opened or closed, that
|
|
67
|
+
* the user actually shared, and it never grants share-reward eligibility.
|
|
68
|
+
* (Renamed from `closed` in 0.3.0: the underlying SDKs guarantee the call
|
|
69
|
+
* completing, not the sheet's lifecycle.)
|
|
68
70
|
*/
|
|
69
71
|
export type SdkShareUiResult = {
|
|
70
|
-
status: "
|
|
72
|
+
status: "completed";
|
|
71
73
|
} | {
|
|
72
74
|
status: "failed";
|
|
73
75
|
code?: string;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,oDAAoD;AACpD,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,QAAQ,CAAA;CAAE,GACxC;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C,mDAAmD;AACnD,MAAM,MAAM,YAAY,GACpB,iBAAiB,GACjB,aAAa,GACb,eAAe,GACf,oBAAoB,GACpB,gBAAgB,GAChB,iBAAiB,GACjB,sBAAsB,GACtB,uBAAuB,GACvB,oBAAoB,CAAC;AAMzB,mEAAmE;AACnE,MAAM,MAAM,4BAA4B,GAAG,cAAc,GAAG,eAAe,GAAG,mBAAmB,CAAC;AAElG;;;;;;GAMG;AACH,MAAM,MAAM,8BAA8B,GACtC;IACE,MAAM,EAAE,QAAQ,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC,4BAA4B,EAAE,mBAAmB,CAAC,CAAC;IACtE,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/B,GACD;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAC3E;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1E;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjE
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
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":"AAGA,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;
|
|
1
|
+
{"version":3,"file":"ads.d.ts","sourceRoot":"","sources":["../../src/rn/ads.ts"],"names":[],"mappings":"AAGA,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
|
@@ -6,6 +6,37 @@ import { runEventFlow } from "../event-flow.js";
|
|
|
6
6
|
import { createDefaultFrameworkLoader } from "./framework-loader.js";
|
|
7
7
|
const DEFAULT_SHOW_TIMEOUT_MS = 60_000;
|
|
8
8
|
const DEFAULT_LOAD_TIMEOUT_MS = 30_000;
|
|
9
|
+
function createAdDeadline(timeoutMs, now = monotonicNow) {
|
|
10
|
+
if (!(timeoutMs > 0)) {
|
|
11
|
+
return { remainingMs: () => undefined, race: (promise) => promise };
|
|
12
|
+
}
|
|
13
|
+
const startedAt = now();
|
|
14
|
+
return {
|
|
15
|
+
remainingMs: () => timeoutMs - (now() - startedAt),
|
|
16
|
+
race: (promise) => new Promise((resolve, reject) => {
|
|
17
|
+
const timer = setTimeout(() => resolve(undefined), timeoutMs);
|
|
18
|
+
// Attaching handlers also sinks a settlement that happens after the
|
|
19
|
+
// deadline already won; the no-op reject/resolve after settling is
|
|
20
|
+
// ignored by promise semantics.
|
|
21
|
+
promise.then((value) => {
|
|
22
|
+
clearTimeout(timer);
|
|
23
|
+
resolve(value);
|
|
24
|
+
}, (error) => {
|
|
25
|
+
clearTimeout(timer);
|
|
26
|
+
reject(error);
|
|
27
|
+
});
|
|
28
|
+
})
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Monotonic elapsed time: a system wall-clock correction while the loader
|
|
33
|
+
* is pending must not shrink or stretch the remaining budget.
|
|
34
|
+
*/
|
|
35
|
+
function monotonicNow() {
|
|
36
|
+
return typeof performance !== "undefined" && typeof performance.now === "function"
|
|
37
|
+
? performance.now()
|
|
38
|
+
: Date.now();
|
|
39
|
+
}
|
|
9
40
|
/**
|
|
10
41
|
* React Native ad adapter over `@apps-in-toss/framework`. Load state is
|
|
11
42
|
* tracked per ad type + ad unit, in-flight duplicate loads share one
|
|
@@ -28,73 +59,28 @@ export function createReactNativeAds(options = {}) {
|
|
|
28
59
|
if (existing) {
|
|
29
60
|
return existing.kind === "loaded" ? Promise.resolve() : existing.promise;
|
|
30
61
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
62
|
+
// Slot updates run inside this promise's settlement — before the
|
|
63
|
+
// caller's await/catch continuation — so a caller that immediately
|
|
64
|
+
// retries after a failure starts a fresh registration, and a caller
|
|
65
|
+
// that immediately shows after a success finds the slot loaded. The
|
|
66
|
+
// identity check keeps a stale task from touching a newer task's slot.
|
|
67
|
+
const promise = new Promise((resolve, reject) => {
|
|
68
|
+
runLoad(adGroupId).then(() => {
|
|
69
|
+
const current = slots.get(id);
|
|
70
|
+
if (current?.kind === "loading" && current.promise === promise) {
|
|
71
|
+
slots.set(id, { kind: "loaded" });
|
|
40
72
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
register: (emit) => framework.loadFullScreenAd({
|
|
47
|
-
options: { adGroupId },
|
|
48
|
-
onEvent: emit,
|
|
49
|
-
onError: (error) => emit({ type: "sdkError", error })
|
|
50
|
-
}),
|
|
51
|
-
reduce: (event) => event.type === "loaded"
|
|
52
|
-
? { done: true, result: undefined }
|
|
53
|
-
: { done: true, result: loadFailure(event.error) },
|
|
54
|
-
onTimeout: () => new SdkError("AD_LOAD_TIMEOUT", "full-screen ad load timed out"),
|
|
55
|
-
timeoutMs: loadTimeoutMs
|
|
56
|
-
});
|
|
57
|
-
if (outcome instanceof SdkError) {
|
|
58
|
-
throw outcome;
|
|
59
|
-
}
|
|
60
|
-
})();
|
|
61
|
-
// If the deadline wins, the orphaned task rejects into this sink.
|
|
62
|
-
task.catch(() => { });
|
|
63
|
-
let timer;
|
|
64
|
-
const deadline = new Promise((_, reject) => {
|
|
65
|
-
if (loadTimeoutMs > 0) {
|
|
66
|
-
timer = setTimeout(() => {
|
|
67
|
-
cancelled = true;
|
|
68
|
-
reject(new SdkError("AD_LOAD_TIMEOUT", "full-screen ad load timed out"));
|
|
69
|
-
}, loadTimeoutMs);
|
|
73
|
+
resolve();
|
|
74
|
+
}, (error) => {
|
|
75
|
+
const current = slots.get(id);
|
|
76
|
+
if (current?.kind === "loading" && current.promise === promise) {
|
|
77
|
+
slots.delete(id);
|
|
70
78
|
}
|
|
79
|
+
reject(error);
|
|
71
80
|
});
|
|
72
|
-
try {
|
|
73
|
-
return await Promise.race([task, deadline]);
|
|
74
|
-
}
|
|
75
|
-
finally {
|
|
76
|
-
if (timer !== undefined)
|
|
77
|
-
clearTimeout(timer);
|
|
78
|
-
}
|
|
79
|
-
})();
|
|
80
|
-
slots.set(id, { kind: "loading", promise: request });
|
|
81
|
-
request
|
|
82
|
-
.then(() => {
|
|
83
|
-
// Promote only when this exact request still owns the slot: a
|
|
84
|
-
// timed-out task resolving late must not mark a newer retry loaded.
|
|
85
|
-
const current = slots.get(id);
|
|
86
|
-
if (current?.kind === "loading" && current.promise === request) {
|
|
87
|
-
slots.set(id, { kind: "loaded" });
|
|
88
|
-
}
|
|
89
|
-
})
|
|
90
|
-
.catch(() => {
|
|
91
|
-
// A failed load frees the slot so the next attempt retries.
|
|
92
|
-
const current = slots.get(id);
|
|
93
|
-
if (current?.kind === "loading" && current.promise === request) {
|
|
94
|
-
slots.delete(id);
|
|
95
|
-
}
|
|
96
81
|
});
|
|
97
|
-
|
|
82
|
+
slots.set(id, { kind: "loading", promise });
|
|
83
|
+
return promise;
|
|
98
84
|
};
|
|
99
85
|
const show = (adGroupId) => {
|
|
100
86
|
const id = adKey("fullscreen", adGroupId);
|
|
@@ -111,65 +97,85 @@ export function createReactNativeAds(options = {}) {
|
|
|
111
97
|
slots.delete(id);
|
|
112
98
|
showing.add(id);
|
|
113
99
|
return (async () => {
|
|
114
|
-
// The deadline covers framework acquisition as well as the show flow:
|
|
115
|
-
// a stalled loader must release the showing slot instead of wedging
|
|
116
|
-
// the ad group forever, and a late-resolving loader must not register
|
|
117
|
-
// a show the deadline already ended.
|
|
118
|
-
let reward;
|
|
119
|
-
let cancelled = false;
|
|
120
100
|
const timedOut = () => ({ status: "failed", reason: "ad show flow timed out" });
|
|
121
101
|
try {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
if (typeof framework.showFullScreenAd.isSupported === "function" &&
|
|
137
|
-
!framework.showFullScreenAd.isSupported()) {
|
|
138
|
-
throw new SdkError("UNSUPPORTED", "full-screen ads are not supported on this app version");
|
|
139
|
-
}
|
|
140
|
-
return await runEventFlow({
|
|
141
|
-
register: (emit) => framework.showFullScreenAd({
|
|
142
|
-
options: { adGroupId },
|
|
143
|
-
onEvent: emit,
|
|
144
|
-
onError: (error) => emit({ type: "sdkError", error })
|
|
145
|
-
}),
|
|
146
|
-
reduce: (event) => {
|
|
147
|
-
if (event.type === "sdkError") {
|
|
148
|
-
const message = errorMessage(event.error);
|
|
149
|
-
return {
|
|
150
|
-
done: true,
|
|
151
|
-
result: { status: "failed", reason: `full-screen ad show failed: ${message}` }
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
return reduceShowEvent(event, () => reward, (value) => (reward = value));
|
|
155
|
-
},
|
|
156
|
-
onTimeout: timedOut,
|
|
157
|
-
timeoutMs: showTimeoutMs
|
|
158
|
-
});
|
|
159
|
-
})();
|
|
160
|
-
try {
|
|
161
|
-
return await Promise.race([task, deadline]);
|
|
102
|
+
// The whole show shares one budget: the loader races it, the event
|
|
103
|
+
// flow gets what remains, and the flow's own deadline produces the
|
|
104
|
+
// timeout result — its subscription cleanup completes before this
|
|
105
|
+
// promise settles, so `showing` is only released after the
|
|
106
|
+
// subscription is gone.
|
|
107
|
+
const deadline = createAdDeadline(showTimeoutMs);
|
|
108
|
+
const framework = await deadline.race(loadFramework());
|
|
109
|
+
if (!framework) {
|
|
110
|
+
return timedOut();
|
|
111
|
+
}
|
|
112
|
+
if (typeof framework.showFullScreenAd.isSupported === "function" &&
|
|
113
|
+
!framework.showFullScreenAd.isSupported()) {
|
|
114
|
+
throw new SdkError("UNSUPPORTED", "full-screen ads are not supported on this app version");
|
|
162
115
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
116
|
+
const remaining = deadline.remainingMs();
|
|
117
|
+
if (remaining !== undefined && remaining <= 0) {
|
|
118
|
+
return timedOut();
|
|
166
119
|
}
|
|
120
|
+
let reward;
|
|
121
|
+
return await runEventFlow({
|
|
122
|
+
register: (emit) => framework.showFullScreenAd({
|
|
123
|
+
options: { adGroupId },
|
|
124
|
+
onEvent: emit,
|
|
125
|
+
onError: (error) => emit({ type: "sdkError", error })
|
|
126
|
+
}),
|
|
127
|
+
reduce: (event) => {
|
|
128
|
+
if (event.type === "sdkError") {
|
|
129
|
+
const message = errorMessage(event.error);
|
|
130
|
+
return {
|
|
131
|
+
done: true,
|
|
132
|
+
result: { status: "failed", reason: `full-screen ad show failed: ${message}` }
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return reduceShowEvent(event, () => reward, (value) => (reward = value));
|
|
136
|
+
},
|
|
137
|
+
onTimeout: timedOut,
|
|
138
|
+
timeoutMs: remaining ?? 0
|
|
139
|
+
});
|
|
167
140
|
}
|
|
168
141
|
finally {
|
|
169
142
|
showing.delete(id);
|
|
170
143
|
}
|
|
171
144
|
})();
|
|
172
145
|
};
|
|
146
|
+
async function runLoad(adGroupId) {
|
|
147
|
+
// One deadline covers framework acquisition AND the provider flow. A
|
|
148
|
+
// loader that wins the race only just — or too late — leaves no budget
|
|
149
|
+
// for the provider registration, which is then skipped entirely.
|
|
150
|
+
const deadline = createAdDeadline(loadTimeoutMs);
|
|
151
|
+
const framework = await deadline.race(loadFramework());
|
|
152
|
+
if (!framework) {
|
|
153
|
+
throw new SdkError("AD_LOAD_TIMEOUT", "full-screen ad load timed out");
|
|
154
|
+
}
|
|
155
|
+
if (typeof framework.loadFullScreenAd.isSupported === "function" &&
|
|
156
|
+
!framework.loadFullScreenAd.isSupported()) {
|
|
157
|
+
throw new SdkError("UNSUPPORTED", "full-screen ads are not supported on this app version");
|
|
158
|
+
}
|
|
159
|
+
const remaining = deadline.remainingMs();
|
|
160
|
+
if (remaining !== undefined && remaining <= 0) {
|
|
161
|
+
throw new SdkError("AD_LOAD_TIMEOUT", "full-screen ad load timed out");
|
|
162
|
+
}
|
|
163
|
+
const outcome = await runEventFlow({
|
|
164
|
+
register: (emit) => framework.loadFullScreenAd({
|
|
165
|
+
options: { adGroupId },
|
|
166
|
+
onEvent: emit,
|
|
167
|
+
onError: (error) => emit({ type: "sdkError", error })
|
|
168
|
+
}),
|
|
169
|
+
reduce: (event) => event.type === "loaded"
|
|
170
|
+
? { done: true, result: undefined }
|
|
171
|
+
: { done: true, result: loadFailure(event.error) },
|
|
172
|
+
onTimeout: () => new SdkError("AD_LOAD_TIMEOUT", "full-screen ad load timed out"),
|
|
173
|
+
timeoutMs: remaining ?? 0
|
|
174
|
+
});
|
|
175
|
+
if (outcome instanceof SdkError) {
|
|
176
|
+
throw outcome;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
173
179
|
async function loadFramework() {
|
|
174
180
|
const result = await loader();
|
|
175
181
|
if (!result.available) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/rn/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EAGzB,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/rn/identity.ts"],"names":[],"mappings":"AAAA,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,CAQxB"}
|
package/dist/rn/identity.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SdkError } from "../index.js";
|
|
2
2
|
import { runSdkGetAnonymousKey, runSdkLogin } from "../identity/platform-contract.js";
|
|
3
|
+
import { adaptOfficialRnIdentity } from "./official-module.js";
|
|
3
4
|
export function createReactNativeIdentity(options = {}) {
|
|
4
5
|
const loader = normalizeIdentityLoader(options.framework);
|
|
5
6
|
const load = async () => {
|
|
@@ -23,6 +24,12 @@ export function normalizeIdentityLoader(framework) {
|
|
|
23
24
|
}
|
|
24
25
|
return async () => ({ available: true, module: framework });
|
|
25
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Default loader: imports the official `@apps-in-toss/framework` lazily and
|
|
29
|
+
* converts its flat export surface (`appLogin`, `getAnonymousKey`) to the
|
|
30
|
+
* shared identity contract. A failed import is never cached (a later call
|
|
31
|
+
* retries); successful loads cache the converted module.
|
|
32
|
+
*/
|
|
26
33
|
function createDefaultRnIdentityLoader() {
|
|
27
34
|
let cached;
|
|
28
35
|
return async () => {
|
|
@@ -30,8 +37,7 @@ function createDefaultRnIdentityLoader() {
|
|
|
30
37
|
return { available: true, module: cached };
|
|
31
38
|
}
|
|
32
39
|
try {
|
|
33
|
-
|
|
34
|
-
cached = framework;
|
|
40
|
+
cached = adaptOfficialRnIdentity(await import("@apps-in-toss/framework"));
|
|
35
41
|
return { available: true, module: cached };
|
|
36
42
|
}
|
|
37
43
|
catch (error) {
|
|
@@ -30,9 +30,9 @@ export interface ReactNativeShare {
|
|
|
30
30
|
/** Creates a share link for an `intoss://` deeplink path. */
|
|
31
31
|
createLink(path: string, ogImageUrl?: string): Promise<string>;
|
|
32
32
|
/**
|
|
33
|
-
* Opens the native share sheet. Resolving `
|
|
34
|
-
*
|
|
35
|
-
* eligibility.
|
|
33
|
+
* Opens the native share sheet. Resolving `completed` means the SDK share
|
|
34
|
+
* call finished — it does not prove the user shared (or even saw the
|
|
35
|
+
* sheet) and never grants reward eligibility.
|
|
36
36
|
*/
|
|
37
37
|
sendMessage(message: string): Promise<SdkShareUiResult>;
|
|
38
38
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notify-share.d.ts","sourceRoot":"","sources":["../../src/rn/notify-share.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,8BAA8B,EACnC,KAAK,gBAAgB,EACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAE7B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EAGtB,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"notify-share.d.ts","sourceRoot":"","sources":["../../src/rn/notify-share.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,8BAA8B,EACnC,KAAK,gBAAgB,EACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAE7B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EAGtB,MAAM,+BAA+B,CAAC;AASvC,MAAM,WAAW,8BAA8B;IAC7C;;;OAGG;IACH,SAAS,CAAC,EAAE,uBAAuB,GAAG,0BAA0B,CAAC;IACjE,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;CACjF;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,GAAE,8BAAmC,GAC3C,uBAAuB,CAazB;AAMD,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,SAAS,CAAC,EAAE,gBAAgB,GAAG,mBAAmB,CAAC;CACpD;AAED,MAAM,WAAW,gBAAgB;IAC/B,6DAA6D;IAC7D,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/D;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACzD;AAED,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,uBAA4B,GACpC,gBAAgB,CAyClB;AAMD,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,8BAA8B,CAAC,WAAW,CAAC,GACrD,0BAA0B,CAQ5B;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,uBAAuB,CAAC,WAAW,CAAC,GAC9C,mBAAmB,CAQrB"}
|
package/dist/rn/notify-share.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SdkError } from "../index.js";
|
|
2
2
|
import { runRequestAgreement } from "../notification/platform-contract.js";
|
|
3
3
|
import { runShareUi, validateSharePath } from "../share/platform-contract.js";
|
|
4
|
+
import { adaptOfficialRnNotification, adaptOfficialRnShare } from "./official-module.js";
|
|
4
5
|
const DEFAULT_AGREEMENT_TIMEOUT_MS = 60_000;
|
|
5
6
|
export function createReactNativeNotification(options = {}) {
|
|
6
7
|
const loader = normalizeNotificationLoader(options.framework);
|
|
@@ -58,7 +59,7 @@ export function createReactNativeShare(options = {}) {
|
|
|
58
59
|
// ---------------------------------------------------------------------------
|
|
59
60
|
export function normalizeNotificationLoader(framework) {
|
|
60
61
|
if (!framework) {
|
|
61
|
-
return
|
|
62
|
+
return createDefaultRnNotificationLoader();
|
|
62
63
|
}
|
|
63
64
|
if (typeof framework === "function") {
|
|
64
65
|
return framework;
|
|
@@ -67,22 +68,46 @@ export function normalizeNotificationLoader(framework) {
|
|
|
67
68
|
}
|
|
68
69
|
export function normalizeShareLoader(framework) {
|
|
69
70
|
if (!framework) {
|
|
70
|
-
return
|
|
71
|
+
return createDefaultRnShareLoader();
|
|
71
72
|
}
|
|
72
73
|
if (typeof framework === "function") {
|
|
73
74
|
return framework;
|
|
74
75
|
}
|
|
75
76
|
return async () => ({ available: true, module: framework });
|
|
76
77
|
}
|
|
77
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Default loaders: import the official `@apps-in-toss/framework` lazily and
|
|
80
|
+
* convert its flat export surface (`requestNotificationAgreement`,
|
|
81
|
+
* `getTossShareLink`, `share`) to the shared contracts. Failed imports are
|
|
82
|
+
* never cached; successful loads cache the converted module.
|
|
83
|
+
*/
|
|
84
|
+
function createDefaultRnNotificationLoader() {
|
|
85
|
+
let cached;
|
|
86
|
+
return async () => {
|
|
87
|
+
if (cached) {
|
|
88
|
+
return { available: true, module: cached };
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
cached = adaptOfficialRnNotification(await import("@apps-in-toss/framework"));
|
|
92
|
+
return { available: true, module: cached };
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
96
|
+
return {
|
|
97
|
+
available: false,
|
|
98
|
+
reason: `failed to import @apps-in-toss/framework: ${message}`
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function createDefaultRnShareLoader() {
|
|
78
104
|
let cached;
|
|
79
105
|
return async () => {
|
|
80
106
|
if (cached) {
|
|
81
107
|
return { available: true, module: cached };
|
|
82
108
|
}
|
|
83
109
|
try {
|
|
84
|
-
|
|
85
|
-
cached = framework;
|
|
110
|
+
cached = adaptOfficialRnShare(await import("@apps-in-toss/framework"));
|
|
86
111
|
return { available: true, module: cached };
|
|
87
112
|
}
|
|
88
113
|
catch (error) {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { IdentityPlatformSdk } from "../identity/platform-contract.js";
|
|
2
|
+
import type { NotificationAgreementParams, NotificationPlatformSdk } from "../notification/platform-contract.js";
|
|
3
|
+
import type { SharePlatformSdk } from "../share/platform-contract.js";
|
|
4
|
+
/**
|
|
5
|
+
* Internal conversion layer between the official `@apps-in-toss/framework`
|
|
6
|
+
* exports and the shared platform contracts. The official React Native SDK
|
|
7
|
+
* (verified against 2.10.10, re-exported from @apps-in-toss/native-modules)
|
|
8
|
+
* exposes these capabilities as flat module functions, while the shared
|
|
9
|
+
* contracts (which match the web SDK's namespaced API) group them under
|
|
10
|
+
* TossAuth/User/Notification/Share. This module performs that translation;
|
|
11
|
+
* it is never exported from a public subpath.
|
|
12
|
+
*
|
|
13
|
+
* Every member of {@link OfficialRnFrameworkModule} is optional: older
|
|
14
|
+
* app/SDK versions may omit any of them, and each adapter surfaces a
|
|
15
|
+
* missing capability as a clear UNSUPPORTED error for that operation
|
|
16
|
+
* instead of guessing a call shape.
|
|
17
|
+
*/
|
|
18
|
+
/** Official `appLogin()` result, preserved verbatim by the identity engine. */
|
|
19
|
+
export interface OfficialAppLoginResult {
|
|
20
|
+
authorizationCode: string;
|
|
21
|
+
referrer: "DEFAULT" | "SANDBOX";
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Official `getAnonymousKey()` success shape. The official function may
|
|
25
|
+
* also resolve the `"ERROR"` sentinel (unknown failure) or `undefined`
|
|
26
|
+
* (app below the feature's minimum version); both are handled by the
|
|
27
|
+
* adapter below.
|
|
28
|
+
*/
|
|
29
|
+
export interface OfficialAnonymousKeyResult {
|
|
30
|
+
type: "HASH";
|
|
31
|
+
hash: string;
|
|
32
|
+
}
|
|
33
|
+
type OfficialFunction<F> = F & {
|
|
34
|
+
isSupported?: () => boolean;
|
|
35
|
+
};
|
|
36
|
+
/** Structural subset of the official React Native framework module. */
|
|
37
|
+
export interface OfficialRnFrameworkModule {
|
|
38
|
+
appLogin?: OfficialFunction<() => Promise<OfficialAppLoginResult>>;
|
|
39
|
+
getAnonymousKey?: OfficialFunction<() => Promise<OfficialAnonymousKeyResult | "ERROR" | undefined>>;
|
|
40
|
+
requestNotificationAgreement?: OfficialFunction<(params: NotificationAgreementParams) => () => void>;
|
|
41
|
+
getTossShareLink?: OfficialFunction<(path: string, ogImageUrl?: string) => Promise<string>>;
|
|
42
|
+
share?: OfficialFunction<(message: {
|
|
43
|
+
message: string;
|
|
44
|
+
}) => Promise<void>>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Converts the official identity exports (`appLogin`, `getAnonymousKey`) to
|
|
48
|
+
* the shared identity contract. Missing functions stay missing so the
|
|
49
|
+
* shared engine reports UNSUPPORTED per operation.
|
|
50
|
+
*/
|
|
51
|
+
export declare function adaptOfficialRnIdentity(module: OfficialRnFrameworkModule): IdentityPlatformSdk;
|
|
52
|
+
/**
|
|
53
|
+
* Converts the official `requestNotificationAgreement` to the shared
|
|
54
|
+
* notification contract. The official params shape matches the internal
|
|
55
|
+
* one exactly, and the returned cleanup function passes through so the
|
|
56
|
+
* event flow owns and invokes it.
|
|
57
|
+
*/
|
|
58
|
+
export declare function adaptOfficialRnNotification(module: OfficialRnFrameworkModule): NotificationPlatformSdk;
|
|
59
|
+
/**
|
|
60
|
+
* Converts the official share exports to the shared share contract:
|
|
61
|
+
* `getTossShareLink(path, ogImageUrl?)` takes positional arguments (the
|
|
62
|
+
* internal contract's object form is unpacked here) and `share` receives
|
|
63
|
+
* the `{ message }` object as-is.
|
|
64
|
+
*/
|
|
65
|
+
export declare function adaptOfficialRnShare(module: OfficialRnFrameworkModule): SharePlatformSdk;
|
|
66
|
+
export {};
|
|
67
|
+
//# sourceMappingURL=official-module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"official-module.d.ts","sourceRoot":"","sources":["../../src/rn/official-module.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,KAAK,EACV,2BAA2B,EAC3B,uBAAuB,EACxB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAyB,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAE7F;;;;;;;;;;;;;GAaG;AAEH,+EAA+E;AAC/E,MAAM,WAAW,sBAAsB;IACrC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,SAAS,GAAG,SAAS,CAAC;CACjC;AAED;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,KAAK,gBAAgB,CAAC,CAAC,IAAI,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,OAAO,CAAA;CAAE,CAAC;AAE/D,uEAAuE;AACvE,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,EAAE,gBAAgB,CAAC,MAAM,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC;IACnE,eAAe,CAAC,EAAE,gBAAgB,CAChC,MAAM,OAAO,CAAC,0BAA0B,GAAG,OAAO,GAAG,SAAS,CAAC,CAChE,CAAC;IACF,4BAA4B,CAAC,EAAE,gBAAgB,CAC7C,CAAC,MAAM,EAAE,2BAA2B,KAAK,MAAM,IAAI,CACpD,CAAC;IACF,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5F,KAAK,CAAC,EAAE,gBAAgB,CAAC,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CAC3E;AAkBD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,yBAAyB,GAAG,mBAAmB,CA6B9F;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,yBAAyB,GAAG,uBAAuB,CAWtG;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,yBAAyB,GAAG,gBAAgB,CAsBxF"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { SdkError } from "../index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Wraps an official function for the internal contract while preserving the
|
|
4
|
+
* original receiver (the official module object, in case the implementation
|
|
5
|
+
* relies on `this`) and an optional `isSupported` flag, so version-gate
|
|
6
|
+
* checks keep working whenever the official SDK exposes them.
|
|
7
|
+
*/
|
|
8
|
+
function preserveSupport(original, wrapper) {
|
|
9
|
+
if (typeof original.isSupported === "function") {
|
|
10
|
+
return Object.assign(wrapper, { isSupported: () => original.isSupported() });
|
|
11
|
+
}
|
|
12
|
+
return wrapper;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Converts the official identity exports (`appLogin`, `getAnonymousKey`) to
|
|
16
|
+
* the shared identity contract. Missing functions stay missing so the
|
|
17
|
+
* shared engine reports UNSUPPORTED per operation.
|
|
18
|
+
*/
|
|
19
|
+
export function adaptOfficialRnIdentity(module) {
|
|
20
|
+
const identity = {};
|
|
21
|
+
if (typeof module.appLogin === "function") {
|
|
22
|
+
const appLogin = module.appLogin;
|
|
23
|
+
identity.TossAuth = {
|
|
24
|
+
login: preserveSupport(appLogin, () => appLogin.call(module))
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if (typeof module.getAnonymousKey === "function") {
|
|
28
|
+
const getAnonymousKey = module.getAnonymousKey;
|
|
29
|
+
identity.User = {
|
|
30
|
+
getAnonymousKey: preserveSupport(getAnonymousKey, async () => {
|
|
31
|
+
const result = await getAnonymousKey.call(module);
|
|
32
|
+
// The official SDK resolves undefined when the installed app is
|
|
33
|
+
// below the feature's minimum version: that is an unsupported
|
|
34
|
+
// environment, not a malformed result.
|
|
35
|
+
if (result === undefined) {
|
|
36
|
+
throw new SdkError("UNSUPPORTED", "the installed app version does not support getAnonymousKey");
|
|
37
|
+
}
|
|
38
|
+
// The "ERROR" sentinel and malformed shapes are rejected by the
|
|
39
|
+
// shared validator (runSdkGetAnonymousKey) like on any platform.
|
|
40
|
+
return result;
|
|
41
|
+
})
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return identity;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Converts the official `requestNotificationAgreement` to the shared
|
|
48
|
+
* notification contract. The official params shape matches the internal
|
|
49
|
+
* one exactly, and the returned cleanup function passes through so the
|
|
50
|
+
* event flow owns and invokes it.
|
|
51
|
+
*/
|
|
52
|
+
export function adaptOfficialRnNotification(module) {
|
|
53
|
+
const notification = {};
|
|
54
|
+
if (typeof module.requestNotificationAgreement === "function") {
|
|
55
|
+
const requestNotificationAgreement = module.requestNotificationAgreement;
|
|
56
|
+
notification.Notification = {
|
|
57
|
+
requestAgreement: preserveSupport(requestNotificationAgreement, (params) => requestNotificationAgreement.call(module, params))
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return notification;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Converts the official share exports to the shared share contract:
|
|
64
|
+
* `getTossShareLink(path, ogImageUrl?)` takes positional arguments (the
|
|
65
|
+
* internal contract's object form is unpacked here) and `share` receives
|
|
66
|
+
* the `{ message }` object as-is.
|
|
67
|
+
*/
|
|
68
|
+
export function adaptOfficialRnShare(module) {
|
|
69
|
+
const share = {};
|
|
70
|
+
if (typeof module.getTossShareLink === "function") {
|
|
71
|
+
const getTossShareLink = module.getTossShareLink;
|
|
72
|
+
share.Share = {
|
|
73
|
+
createLink: preserveSupport(getTossShareLink, ({ path, ogImageUrl }) => ogImageUrl !== undefined
|
|
74
|
+
? getTossShareLink.call(module, path, ogImageUrl)
|
|
75
|
+
: getTossShareLink.call(module, path))
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
if (typeof module.share === "function") {
|
|
79
|
+
const officialShare = module.share;
|
|
80
|
+
share.Share = {
|
|
81
|
+
...share.Share,
|
|
82
|
+
sendMessage: preserveSupport(officialShare, (message) => officialShare.call(module, message))
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return share;
|
|
86
|
+
}
|
package/dist/rn/storage.js
CHANGED
|
@@ -52,7 +52,9 @@ function createDefaultRnStorageLoader() {
|
|
|
52
52
|
return { available: true, module: cached };
|
|
53
53
|
}
|
|
54
54
|
try {
|
|
55
|
-
|
|
55
|
+
// The official RN SDK exposes Storage under the same namespaced shape
|
|
56
|
+
// as the shared contract, so no conversion is needed.
|
|
57
|
+
const framework = await import("@apps-in-toss/framework");
|
|
56
58
|
cached = framework;
|
|
57
59
|
return { available: true, module: cached };
|
|
58
60
|
}
|
|
@@ -31,10 +31,10 @@ export type SharePlatformLoader = () => Promise<{
|
|
|
31
31
|
*/
|
|
32
32
|
export declare function validateSharePath(path: string): string;
|
|
33
33
|
/**
|
|
34
|
-
* Wraps the share-UI call: a resolution means the
|
|
35
|
-
*
|
|
36
|
-
* never grants reward eligibility. Rejections
|
|
37
|
-
* platform's error code/message preserved.
|
|
34
|
+
* Wraps the share-UI call: a resolution means ONLY that the SDK share call
|
|
35
|
+
* completed ("completed") — it never proves the share sheet opened or that
|
|
36
|
+
* the user actually shared, and never grants reward eligibility. Rejections
|
|
37
|
+
* surface as failed with the platform's error code/message preserved.
|
|
38
38
|
*/
|
|
39
39
|
export declare function runShareUi(platform: SharePlatformSdk, message: string): Promise<SdkShareUiResult>;
|
|
40
40
|
export {};
|
|
@@ -13,15 +13,15 @@ export function validateSharePath(path) {
|
|
|
13
13
|
return path;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
* Wraps the share-UI call: a resolution means the
|
|
17
|
-
*
|
|
18
|
-
* never grants reward eligibility. Rejections
|
|
19
|
-
* platform's error code/message preserved.
|
|
16
|
+
* Wraps the share-UI call: a resolution means ONLY that the SDK share call
|
|
17
|
+
* completed ("completed") — it never proves the share sheet opened or that
|
|
18
|
+
* the user actually shared, and never grants reward eligibility. Rejections
|
|
19
|
+
* surface as failed with the platform's error code/message preserved.
|
|
20
20
|
*/
|
|
21
21
|
export async function runShareUi(platform, message) {
|
|
22
22
|
try {
|
|
23
23
|
await platform.Share.sendMessage({ message });
|
|
24
|
-
return { status: "
|
|
24
|
+
return { status: "completed" };
|
|
25
25
|
}
|
|
26
26
|
catch (error) {
|
|
27
27
|
const code = readErrorCode(error);
|
package/dist/web/identity.js
CHANGED
|
@@ -49,7 +49,7 @@ export function createWebStorage(options = {}) {
|
|
|
49
49
|
}
|
|
50
50
|
function normalizeWebIdentityLoader(framework) {
|
|
51
51
|
if (!framework) {
|
|
52
|
-
return
|
|
52
|
+
return createDefaultWebIdentityLoader();
|
|
53
53
|
}
|
|
54
54
|
if (typeof framework === "function") {
|
|
55
55
|
return framework;
|
|
@@ -58,21 +58,44 @@ function normalizeWebIdentityLoader(framework) {
|
|
|
58
58
|
}
|
|
59
59
|
function normalizeWebStorageLoader(framework) {
|
|
60
60
|
if (!framework) {
|
|
61
|
-
return
|
|
61
|
+
return createDefaultWebStorageLoader();
|
|
62
62
|
}
|
|
63
63
|
if (typeof framework === "function") {
|
|
64
64
|
return framework;
|
|
65
65
|
}
|
|
66
66
|
return async () => ({ available: true, module: framework });
|
|
67
67
|
}
|
|
68
|
-
|
|
68
|
+
// The web SDK exposes the shared namespaced contract shapes directly, so
|
|
69
|
+
// the default loaders consume the official module without any conversion
|
|
70
|
+
// or type assertion; a failed import is never cached, successful loads are.
|
|
71
|
+
function createDefaultWebIdentityLoader() {
|
|
69
72
|
let cached;
|
|
70
73
|
return async () => {
|
|
71
74
|
if (cached) {
|
|
72
75
|
return { available: true, module: cached };
|
|
73
76
|
}
|
|
74
77
|
try {
|
|
75
|
-
const framework =
|
|
78
|
+
const framework = await import("@apps-in-toss/web-framework");
|
|
79
|
+
cached = framework;
|
|
80
|
+
return { available: true, module: cached };
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
84
|
+
return {
|
|
85
|
+
available: false,
|
|
86
|
+
reason: `failed to import @apps-in-toss/web-framework: ${message}`
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function createDefaultWebStorageLoader() {
|
|
92
|
+
let cached;
|
|
93
|
+
return async () => {
|
|
94
|
+
if (cached) {
|
|
95
|
+
return { available: true, module: cached };
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const framework = await import("@apps-in-toss/web-framework");
|
|
76
99
|
cached = framework;
|
|
77
100
|
return { available: true, module: cached };
|
|
78
101
|
}
|
|
@@ -28,8 +28,9 @@ export interface WebShare {
|
|
|
28
28
|
/** Creates a share link for an `intoss://` deeplink path. */
|
|
29
29
|
createLink(path: string, ogImageUrl?: string): Promise<string>;
|
|
30
30
|
/**
|
|
31
|
-
* Opens the native share sheet; `
|
|
32
|
-
* never grants reward
|
|
31
|
+
* Opens the native share sheet; `completed` means only that the SDK share
|
|
32
|
+
* call finished — it never proves the user shared and never grants reward
|
|
33
|
+
* eligibility.
|
|
33
34
|
*/
|
|
34
35
|
sendMessage(message: string): Promise<SdkShareUiResult>;
|
|
35
36
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notify-share.d.ts","sourceRoot":"","sources":["../../src/web/notify-share.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,8BAA8B,EACnC,KAAK,gBAAgB,EACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAE7B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EAGtB,MAAM,+BAA+B,CAAC;AAIvC,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,SAAS,CAAC,EAAE,uBAAuB,GAAG,0BAA0B,CAAC;IACjE,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;CACjF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,CAa3F;AAED,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,SAAS,CAAC,EAAE,gBAAgB,GAAG,mBAAmB,CAAC;CACpD;AAED,MAAM,WAAW,QAAQ;IACvB,6DAA6D;IAC7D,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/D
|
|
1
|
+
{"version":3,"file":"notify-share.d.ts","sourceRoot":"","sources":["../../src/web/notify-share.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,8BAA8B,EACnC,KAAK,gBAAgB,EACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAE7B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EAGtB,MAAM,+BAA+B,CAAC;AAIvC,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,SAAS,CAAC,EAAE,uBAAuB,GAAG,0BAA0B,CAAC;IACjE,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;CACjF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,CAa3F;AAED,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,SAAS,CAAC,EAAE,gBAAgB,GAAG,mBAAmB,CAAC;CACpD;AAED,MAAM,WAAW,QAAQ;IACvB,6DAA6D;IAC7D,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/D;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACzD;AAED,wBAAgB,cAAc,CAAC,OAAO,GAAE,eAAoB,GAAG,QAAQ,CAwCtE"}
|
package/dist/web/notify-share.js
CHANGED
|
@@ -54,7 +54,7 @@ export function createWebShare(options = {}) {
|
|
|
54
54
|
}
|
|
55
55
|
function normalizeWebNotificationLoader(framework) {
|
|
56
56
|
if (!framework) {
|
|
57
|
-
return
|
|
57
|
+
return createDefaultWebNotificationLoader();
|
|
58
58
|
}
|
|
59
59
|
if (typeof framework === "function") {
|
|
60
60
|
return framework;
|
|
@@ -63,21 +63,43 @@ function normalizeWebNotificationLoader(framework) {
|
|
|
63
63
|
}
|
|
64
64
|
function normalizeWebShareLoader(framework) {
|
|
65
65
|
if (!framework) {
|
|
66
|
-
return
|
|
66
|
+
return createDefaultWebShareLoader();
|
|
67
67
|
}
|
|
68
68
|
if (typeof framework === "function") {
|
|
69
69
|
return framework;
|
|
70
70
|
}
|
|
71
71
|
return async () => ({ available: true, module: framework });
|
|
72
72
|
}
|
|
73
|
-
|
|
73
|
+
// See createDefaultWebIdentityLoader in ./identity.ts: the web SDK already
|
|
74
|
+
// matches the shared contract shapes, so no conversion or assertion is used.
|
|
75
|
+
function createDefaultWebNotificationLoader() {
|
|
74
76
|
let cached;
|
|
75
77
|
return async () => {
|
|
76
78
|
if (cached) {
|
|
77
79
|
return { available: true, module: cached };
|
|
78
80
|
}
|
|
79
81
|
try {
|
|
80
|
-
const framework =
|
|
82
|
+
const framework = await import("@apps-in-toss/web-framework");
|
|
83
|
+
cached = framework;
|
|
84
|
+
return { available: true, module: cached };
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
88
|
+
return {
|
|
89
|
+
available: false,
|
|
90
|
+
reason: `failed to import @apps-in-toss/web-framework: ${message}`
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function createDefaultWebShareLoader() {
|
|
96
|
+
let cached;
|
|
97
|
+
return async () => {
|
|
98
|
+
if (cached) {
|
|
99
|
+
return { available: true, module: cached };
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
const framework = await import("@apps-in-toss/web-framework");
|
|
81
103
|
cached = framework;
|
|
82
104
|
return { available: true, module: cached };
|
|
83
105
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ait-kit/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Frontend SDK adapters for Apps in Toss mini apps: shared contracts plus per-runtime entry points.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
"prepack": "bun run build"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"@apps-in-toss/framework": "
|
|
53
|
-
"@apps-in-toss/web-framework": "
|
|
52
|
+
"@apps-in-toss/framework": ">=2.10.10",
|
|
53
|
+
"@apps-in-toss/web-framework": ">=3.4.0"
|
|
54
54
|
},
|
|
55
55
|
"peerDependenciesMeta": {
|
|
56
56
|
"@apps-in-toss/framework": {
|