@amplytools/react-native-amply-sdk 0.9.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/AmplyReactNative.podspec +1 -1
  2. package/android/build.gradle +1 -1
  3. package/android/src/main/java/tools/amply/sdk/reactnative/AmplyModule.kt +6 -0
  4. package/android/src/main/java/tools/amply/sdk/reactnative/core/AmplyClient.kt +8 -0
  5. package/android/src/main/java/tools/amply/sdk/reactnative/core/DefaultAmplyClient.kt +29 -5
  6. package/android/src/newarch/java/tools/amply/sdk/reactnative/NativeAmplyModuleSpec.java +4 -0
  7. package/android/src/newarch/jni/AmplyReactNative-generated.cpp +6 -0
  8. package/dist/src/__tests__/campaignResolved.test.js +16 -4
  9. package/dist/src/__tests__/gateRegistrationLifecycle.test.d.ts +2 -0
  10. package/dist/src/__tests__/gateRegistrationLifecycle.test.d.ts.map +1 -0
  11. package/dist/src/__tests__/gateRegistrationLifecycle.test.js +215 -0
  12. package/dist/src/index.d.ts +11 -1
  13. package/dist/src/index.d.ts.map +1 -1
  14. package/dist/src/index.js +177 -38
  15. package/dist/src/nativeSpecs/NativeAmplyModule.d.ts +9 -0
  16. package/dist/src/nativeSpecs/NativeAmplyModule.d.ts.map +1 -1
  17. package/dist/tsconfig.tsbuildinfo +1 -1
  18. package/ios/Sources/AmplyReactNative/AmplyModule.mm +65 -12
  19. package/ios/Sources/AmplyReactNative/AmplyReactNative/AmplyReactNative-generated.mm +7 -0
  20. package/ios/Sources/AmplyReactNative/AmplyReactNative/AmplyReactNative.h +1 -0
  21. package/package.json +1 -1
  22. package/scripts/check-spec-parity.sh +82 -0
  23. package/src/__tests__/campaignResolved.test.ts +23 -5
  24. package/src/__tests__/gateRegistrationLifecycle.test.ts +281 -0
  25. package/src/index.ts +193 -41
  26. package/src/nativeSpecs/NativeAmplyModule.ts +9 -0
package/dist/src/index.js CHANGED
@@ -4,9 +4,90 @@ export { useAmplySystemEvents } from './hooks/useAmplySystemEvents';
4
4
  export { formatSystemEventLabel } from './systemEventUtils';
5
5
  let deepLinkRegistered = false;
6
6
  let debugLogListenerRegistered = false;
7
- const registeredGates = new Set();
8
7
  const deepLinkSubscriptions = new Set();
9
8
  const campaignPresenterSubscriptions = new Set();
9
+ /**
10
+ * What is registered NATIVELY, keyed by gate baseUrl — at most one entry per URL, because a
11
+ * second `registerGate` on the same URL evicts the first rather than stacking on top of it.
12
+ *
13
+ * This used to be a `Set<string>` written the moment a native call was made, whether or not
14
+ * that call did anything. Three defects came out of that one optimistic write: two presenters
15
+ * both showing a single presentation, a withdrawal that left the native gate live, and a
16
+ * registration made before `initialize` being lost for the lifetime of the process.
17
+ */
18
+ const gateRegistrations = new Map();
19
+ /**
20
+ * Identity for a gate registration. Withdrawal cannot be keyed by URL alone: an unsubscribe
21
+ * handed out for a registration that has since been evicted would otherwise withdraw whatever
22
+ * holds that URL now, killing its replacement. A stale handle must be inert.
23
+ */
24
+ let nextGateRegistrationId = 1;
25
+ const pendingRegistrations = [];
26
+ /** True when the native module exists AND the SDK behind it has been initialised. */
27
+ function isSdkUp() {
28
+ try {
29
+ return getNativeModule().isInitialized();
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ /**
36
+ * Runs [apply] now if the SDK is up, otherwise parks it until [initialize] completes.
37
+ * Returns a canceller so a caller that withdraws before initialisation is never replayed.
38
+ */
39
+ function applyWhenSdkIsUp(apply) {
40
+ if (isSdkUp()) {
41
+ apply();
42
+ return () => { };
43
+ }
44
+ const pending = {
45
+ cancelled: false,
46
+ apply: () => {
47
+ if (!pending.cancelled) {
48
+ apply();
49
+ }
50
+ },
51
+ };
52
+ pendingRegistrations.push(pending);
53
+ return () => {
54
+ pending.cancelled = true;
55
+ };
56
+ }
57
+ function replayPendingRegistrations() {
58
+ const queued = pendingRegistrations.splice(0, pendingRegistrations.length);
59
+ queued.forEach(pending => {
60
+ try {
61
+ pending.apply();
62
+ }
63
+ catch (error) {
64
+ console.warn('[Amply] Failed to apply a registration deferred until initialize', error);
65
+ }
66
+ });
67
+ }
68
+ /**
69
+ * Withdraws the gate registered for [baseUrl], on both sides. A no-op when nothing is
70
+ * registered, so callers do not need to check first.
71
+ */
72
+ function withdrawGate(baseUrl, onlyIfId) {
73
+ const registration = gateRegistrations.get(baseUrl);
74
+ if (!registration) {
75
+ return;
76
+ }
77
+ // Compare before clearing, the same rule the SDK's own listener seams follow: a caller
78
+ // holding a stale handle must not withdraw the registration that replaced it.
79
+ if (onlyIfId !== undefined && registration.id !== onlyIfId) {
80
+ return;
81
+ }
82
+ gateRegistrations.delete(baseUrl);
83
+ registration.removeSubscription();
84
+ try {
85
+ getNativeModule().unregisterGate(baseUrl);
86
+ }
87
+ catch (error) {
88
+ console.warn('[Amply] Failed to unregister gate', baseUrl, error);
89
+ }
90
+ }
10
91
  /**
11
92
  * Format a debug log entry for console output using new format.
12
93
  */
@@ -51,12 +132,15 @@ function ensureDebugLogListener() {
51
132
  });
52
133
  }
53
134
  async function ensureDeepLinkRegistration() {
54
- if (!deepLinkRegistered) {
55
- console.log('[Amply] Calling registerDeepLinkListener on native module');
135
+ if (deepLinkRegistered) {
136
+ return;
137
+ }
138
+ // The flag is set inside apply(), not here: native refuses while the SDK is down, and
139
+ // recording that refusal as success is what stranded the listener for the whole process.
140
+ applyWhenSdkIsUp(() => {
56
141
  getNativeModule().registerDeepLinkListener();
57
142
  deepLinkRegistered = true;
58
- console.log('[Amply] registerDeepLinkListener completed');
59
- }
143
+ });
60
144
  }
61
145
  function trackDeepLinkSubscription(subscription) {
62
146
  let removed = false;
@@ -78,6 +162,8 @@ export async function initialize(config) {
78
162
  ensureDebugLogListener();
79
163
  }
80
164
  await getNativeModule().initialize(config);
165
+ // Anything the host registered before this point was parked rather than lost.
166
+ replayPendingRegistrations();
81
167
  }
82
168
  /**
83
169
  * Set the user ID for analytics. Pass null to clear.
@@ -182,47 +268,95 @@ function trackCampaignPresenterSubscription(subscription) {
182
268
  * ad lifecycles into the single result you report. A synchronous throw → `unavailable`
183
269
  * (fail-open).
184
270
  *
185
- * @returns an unsubscribe function.
271
+ * One presenter per `baseUrl`: registering the same URL again REPLACES the previous
272
+ * presenter and re-applies the options, rather than adding a second one. Two presenters on
273
+ * one URL would both be handed the same presentation, so both would show UI and the outcome
274
+ * would be decided by whichever reported first.
275
+ *
276
+ * Safe to call before {@link initialize} — the registration is held and applied once the SDK
277
+ * is up. Withdrawing before then cancels it instead.
278
+ *
279
+ * @returns an unsubscribe function. It withdraws the NATIVE gate as well as this
280
+ * subscription; a gate left registered behind a departed presenter parks the next gated call
281
+ * on that URL for its whole fail-open timeout, silently.
186
282
  */
187
283
  export async function registerGate(baseUrl, presenter, opts) {
188
284
  var _a, _b;
189
285
  const onAbort = (_a = opts === null || opts === void 0 ? void 0 : opts.onAbort) !== null && _a !== void 0 ? _a : 'cancel';
190
286
  const timeoutMs = (_b = opts === null || opts === void 0 ? void 0 : opts.timeoutMs) !== null && _b !== void 0 ? _b : 0;
191
- if (!registeredGates.has(baseUrl)) {
192
- getNativeModule().registerGate(baseUrl, onAbort, timeoutMs);
193
- registeredGates.add(baseUrl);
194
- }
195
- const nativeModule = getNativeModule();
196
- const subscription = nativeModule.onCampaignPresent((event) => {
197
- const { url, params, info, mediationId } = event;
198
- // The native side routes by baseUrl, but guard here too in case multiple gates
199
- // share the single onCampaignPresent channel.
200
- if (baseUrl && url && !url.startsWith(baseUrl)) {
201
- return;
202
- }
203
- let settled = false;
204
- const report = (result) => {
205
- if (settled) {
206
- return;
207
- }
208
- settled = true;
209
- nativeModule.resolveCampaign(mediationId, result);
210
- };
211
- const resolution = {
212
- completed: () => report('Completed'),
213
- dismissed: () => report('Dismissed'),
214
- unavailable: () => report('Unavailable'),
215
- };
287
+ const registrationId = nextGateRegistrationId++;
288
+ const attach = () => {
289
+ // Evict at APPLY time, not at call time. Two registrations made before `initialize` are
290
+ // both only queued, so a call-time eviction would find nothing in the registry to evict —
291
+ // and both would then attach at replay, the second overwriting the map entry while the
292
+ // first subscription stayed live. That is the duplicate-presenter defect on another path.
293
+ withdrawGate(baseUrl);
294
+ const nativeModule = getNativeModule();
295
+ nativeModule.registerGate(baseUrl, onAbort, timeoutMs);
296
+ let subscription;
216
297
  try {
217
- presenter((params !== null && params !== void 0 ? params : {}), info, resolution);
298
+ subscription = nativeModule.onCampaignPresent((event) => {
299
+ const { url, params, info, mediationId } = event;
300
+ // The native side routes by baseUrl, but guard here too because every gate shares the
301
+ // single onCampaignPresent channel.
302
+ if (baseUrl && url && !url.startsWith(baseUrl)) {
303
+ return;
304
+ }
305
+ let settled = false;
306
+ const report = (result) => {
307
+ if (settled) {
308
+ return;
309
+ }
310
+ settled = true;
311
+ nativeModule.resolveCampaign(mediationId, result);
312
+ };
313
+ const resolution = {
314
+ completed: () => report('Completed'),
315
+ dismissed: () => report('Dismissed'),
316
+ unavailable: () => report('Unavailable'),
317
+ };
318
+ try {
319
+ presenter((params !== null && params !== void 0 ? params : {}), info, resolution);
320
+ }
321
+ catch (error) {
322
+ // Presenter failure is an infra failure, never a user dismiss → Unavailable.
323
+ console.warn('[Amply] gate presenter threw; reporting Unavailable (fail-open)', error);
324
+ report('Unavailable');
325
+ }
326
+ });
218
327
  }
219
328
  catch (error) {
220
- // Presenter failure is an infra failure, never a user dismiss → Unavailable.
221
- console.warn('[Amply] gate presenter threw; reporting Unavailable (fail-open)', error);
222
- report('Unavailable');
329
+ // The native gate is already registered at this point. Leaving it would be the exact
330
+ // defect this whole change exists to remove — a gate with no presenter behind it — and
331
+ // nothing would be tracked to withdraw it later, so withdraw it here.
332
+ console.warn('[Amply] Failed to subscribe a gate presenter; withdrawing the gate', error);
333
+ try {
334
+ nativeModule.unregisterGate(baseUrl);
335
+ }
336
+ catch (withdrawError) {
337
+ console.warn('[Amply] Failed to withdraw the gate after a failed subscribe', withdrawError);
338
+ }
339
+ throw error;
223
340
  }
224
- });
225
- return trackCampaignPresenterSubscription(subscription);
341
+ gateRegistrations.set(baseUrl, {
342
+ id: registrationId,
343
+ removeSubscription: () => { var _a; return (_a = subscription === null || subscription === void 0 ? void 0 : subscription.remove) === null || _a === void 0 ? void 0 : _a.call(subscription); },
344
+ });
345
+ };
346
+ const cancelPending = applyWhenSdkIsUp(attach);
347
+ let withdrawn = false;
348
+ const unsubscribe = () => {
349
+ if (withdrawn) {
350
+ return;
351
+ }
352
+ withdrawn = true;
353
+ cancelPending();
354
+ // Only if THIS registration still holds the URL — see withdrawGate.
355
+ withdrawGate(baseUrl, registrationId);
356
+ campaignPresenterSubscriptions.delete(unsubscribe);
357
+ };
358
+ campaignPresenterSubscriptions.add(unsubscribe);
359
+ return unsubscribe;
226
360
  }
227
361
  export async function getRecentEvents(limit) {
228
362
  return getNativeModule().getRecentEvents(limit);
@@ -296,7 +430,12 @@ export function removeAllListeners() {
296
430
  }
297
431
  });
298
432
  campaignPresenterSubscriptions.clear();
299
- registeredGates.clear();
433
+ // Each unsubscribe above withdraws its own gate. Anything still here was registered by a
434
+ // path that did not go through registerGate's tracker; withdraw it too rather than just
435
+ // forgetting it, which is what the old `registeredGates.clear()` did — leaving JS believing
436
+ // nothing was registered while the gates were still live natively.
437
+ Array.from(gateRegistrations.keys()).forEach(withdrawGate);
438
+ pendingRegistrations.length = 0;
300
439
  }
301
440
  export function addSystemEventsListener(listener) {
302
441
  return addSystemEventListener(listener);
@@ -179,6 +179,15 @@ export interface Spec extends TurboModule {
179
179
  * @param timeoutMs Max time the gate waits for a presenter result before failing open.
180
180
  */
181
181
  registerGate(baseUrl: string, onAbort: string, timeoutMs: number): void;
182
+ /**
183
+ * Withdraw the gate registered for `baseUrl`. A no-op when none is registered.
184
+ *
185
+ * Required for withdrawal to mean anything: the gate registry is process-scoped, so a gate
186
+ * left registered by a presenter that has gone away parks the next gated call on that URL
187
+ * for its whole fail-open timeout — with no crash, no error and no console trace.
188
+ * @param baseUrl The gate action base URL passed to {@link registerGate}.
189
+ */
190
+ unregisterGate(baseUrl: string): void;
182
191
  getRecentEvents(limit: number): Promise<EventRecord[]>;
183
192
  getDataSetSnapshot(type: DataSetType): Promise<DataSetSnapshot>;
184
193
  registerDeepLinkListener(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"NativeAmplyModule.d.ts","sourceRoot":"","sources":["../../../src/nativeSpecs/NativeAmplyModule.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"NativeAmplyModule.d.ts","sourceRoot":"","sources":["../../../src/nativeSpecs/NativeAmplyModule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,2CAA2C,CAAC;AAE5E,KAAK,OAAO,GAAG;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAC,CAAC;AAExC;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEpE,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE5C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC;AAE7C,MAAM,MAAM,2BAA2B,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE/D,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,aAAa,EAAE,2BAA2B,CAAC;IAC3C,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,mBAAmB,EAAE,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,WAAW,GACnB;IAAC,IAAI,EAAE,SAAS,CAAA;CAAC,GACjB;IAAC,IAAI,EAAE,OAAO,CAAA;CAAC,GACf;IAAC,IAAI,EAAE,SAAS,CAAA;CAAC,GACjB;IAAC,IAAI,EAAE,UAAU,CAAA;CAAC,GAClB;IAAC,IAAI,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,kBAAkB,CAAA;CAAC,GACnD;IAAC,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,kBAAkB,EAAE,CAAA;CAAC,CAAC;AAElD,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,WAAW,GAAG,aAAa,CAAC;AAEvE;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,GACpB;IAAC,OAAO,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,UAAU,CAAA;CAAC,GACtD;IAAC,OAAO,EAAE,WAAW,CAAA;CAAC,CAAC;AAE3B;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,UAAU,CAAC,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,aAAa,IAAI,OAAO,CAAC;IACzB,KAAK,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD;;;;;;;;;;;;;OAaG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACjE;;;;;OAKG;IACH,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3D;;;;;;;OAOG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACxE;;;;;;;OAOG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACvD,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAChE,wBAAwB,IAAI,IAAI,CAAC;IACjC;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IACvC;;;OAGG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC;;;OAGG;IACH,WAAW,IAAI,MAAM,CAAC;IACtB;;;OAGG;IACH,mBAAmB,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/C;;;;OAIG;IACH,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD;;;OAGG;IACH,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC;;OAEG;IACH,qBAAqB,IAAI,IAAI,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,YAAY,CAAC,kBAAkB,CAAC,CAAC;IACzD,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,aAAa,CAAC,CAAC;IACjD,QAAQ,CAAC,iBAAiB,EAAE,YAAY,CAAC,oBAAoB,CAAC,CAAC;IAC/D,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;;AAED,wBAA+D"}