@usergist/feedback-react-native 0.2.0-beta.1 → 0.2.0-beta.3

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 (42) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +5 -3
  3. package/dist/UserGist.d.ts +6 -0
  4. package/dist/UserGist.d.ts.map +1 -1
  5. package/dist/UserGist.js +139 -83
  6. package/dist/UserGist.js.map +1 -1
  7. package/dist/index.d.ts +2 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/internal/context.d.ts +1 -1
  10. package/dist/internal/context.js +1 -1
  11. package/dist/internal/engine.d.ts +6 -0
  12. package/dist/internal/engine.d.ts.map +1 -1
  13. package/dist/internal/engine.js +88 -33
  14. package/dist/internal/engine.js.map +1 -1
  15. package/dist/internal/identity-lifecycle.d.ts +16 -0
  16. package/dist/internal/identity-lifecycle.d.ts.map +1 -0
  17. package/dist/internal/identity-lifecycle.js +96 -0
  18. package/dist/internal/identity-lifecycle.js.map +1 -0
  19. package/dist/internal/mutation-queue.d.ts.map +1 -1
  20. package/dist/internal/mutation-queue.js +12 -2
  21. package/dist/internal/mutation-queue.js.map +1 -1
  22. package/dist/internal/push-subscription.d.ts +11 -0
  23. package/dist/internal/push-subscription.d.ts.map +1 -0
  24. package/dist/internal/push-subscription.js +20 -0
  25. package/dist/internal/push-subscription.js.map +1 -0
  26. package/dist/internal/session-revocations.d.ts +5 -0
  27. package/dist/internal/session-revocations.d.ts.map +1 -0
  28. package/dist/internal/session-revocations.js +58 -0
  29. package/dist/internal/session-revocations.js.map +1 -0
  30. package/dist/internal/storage.d.ts +2 -0
  31. package/dist/internal/storage.d.ts.map +1 -1
  32. package/dist/internal/storage.js +75 -60
  33. package/dist/internal/storage.js.map +1 -1
  34. package/dist/internal/transport.d.ts +7 -2
  35. package/dist/internal/transport.d.ts.map +1 -1
  36. package/dist/internal/transport.js +25 -7
  37. package/dist/internal/transport.js.map +1 -1
  38. package/dist/internal/user-state.d.ts +2 -1
  39. package/dist/internal/user-state.d.ts.map +1 -1
  40. package/dist/internal/user-state.js +3 -2
  41. package/dist/internal/user-state.js.map +1 -1
  42. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0-beta.3 — durable instruction receipts
4
+
5
+ - Save instruction delivery state before requesting display, preventing replays after a failed storage write or interrupted delivery.
6
+ - Recheck the active identity after saving a receipt so an account change cannot display a stale instruction.
7
+ - Add regression coverage for concurrent delivery, repeated SDK recreation, offline acknowledgements, and failed receipt persistence.
8
+ - Maximum-impressions enforcement also requires the coordinated API update. Expo remains on the prerelease `next` channel.
9
+
10
+ ## 0.2.0-beta.2 — identity lifecycle
11
+
12
+ - Serialize explicit token invalidation with registration, remove invalidated retry candidates, and preserve consent-based re-enable behavior.
13
+ - Confirmed identity state and asynchronous completion, with backend token renewal and retained account identity after expiration.
14
+ - Property set/unset using the active session; profile PII follows the app's server allowlist, while event filtering remains in place.
15
+ - Installation-bound credentials, anonymous ownership proof, and canonical profile adoption on identify.
16
+ - Local account reset with cancellation and independent durable logout cleanup; stale responses cannot restore the old account.
17
+ - Push subscription state reflects server acknowledgement; OS tokens survive restart and retry after consent, connectivity, or identity changes.
18
+
19
+ Requires the coordinated backend lifecycle deployment. See the [identity integration guide](https://usergist.com/docs/integrations/identity) for backend requirements and account-switching guidance.
20
+
21
+
3
22
  ## 0.2.0-beta.1
4
23
 
5
24
  - Add startup presentation readiness: initialize with `presentationPaused`, then call `resumePresentation()` after the loaded screen is ready.
package/README.md CHANGED
@@ -1,11 +1,13 @@
1
1
  # @usergist/feedback-react-native
2
2
 
3
+ For account IDs, backend-verified guests, token expiry, property updates, and logout, see [the identity integration guide](https://usergist.com/docs/integrations/identity). The identity lifecycle APIs require SDK **0.2.0-beta.2** and the coordinated backend update; verify the installed version before copying examples into an older app.
4
+
5
+
3
6
  Production userGist SDK for React Native and the behavioral reference for the
4
7
  iOS, Android, and Flutter packages. Use the dashboard's SDK setup flow to
5
8
  verify authentication and ingestion. The userGist APNs and FCM paths have
6
9
  passed end-to-end physical-device validation; each host app still needs its own
7
- provider credentials, identifiers, native callback setup, and signed-device
8
- acceptance test.
10
+ provider credentials, identifiers, native callback setup, and confirmation that a test notification arrives.
9
11
 
10
12
  ## Expo
11
13
 
@@ -102,7 +104,7 @@ AppRegistry.registerComponent('app', () => App)
102
104
  | `await UserGist.identifyAsync(userId, props?, subjectToken)` | Backward-compatible async identity API returning `synced`, `queued`, or `rejected`. |
103
105
  | `UserGist.track(name, props?)` | Enqueues a stable event id and immediately evaluates only server-authorized client-side campaigns; all other decisions remain server-authoritative. |
104
106
  | `await UserGist.setConsent({ analytics?, feedback?, push?, survey? })` | Persists and synchronizes the transition, refreshes targeting rules, then resolves with `true`; returns `false` when synchronization fails. |
105
- | `await UserGist.reset()` | Cancels in-flight, clears queue, rotates anonymous id, wipes caches, and resolves after the new anonymous session is ready. |
107
+ | `await UserGist.reset()` | Cancels in-flight, clears queue, rotates anonymous id, wipes caches, and resolves after local cleanup; remote logout and new-session setup retry independently. |
106
108
  | `UserGist.setThemeOverrides(theme)` | Global theme applied under per-prompt theme. |
107
109
  | `UserGist.flush()` | Best-effort flush. |
108
110
  | `UserGist.setDebug(boolean)` | Toggle the debug trace logger at runtime. |
@@ -1,3 +1,5 @@
1
+ import { setPushSubscriptionStateHandler } from './internal/push-subscription.js';
2
+ import { setIdentityStateHandler, setSubjectTokenProvider, getIdentityState } from './internal/identity-lifecycle.js';
1
3
  import type { Consent, EventPropertyValue, PromptTheme, SdkConfig, SurveyAnswerRecord, SurveyAnswerValue, SurveyAttemptSource, SurveyCampaignWithFlow, SurveySummary, CreateSurveyAttemptResponse, JsonAction, InAppCtaAction } from '@usergist/sdk-core/mobile';
2
4
  import { logTrace, getTraces, type SdkDiagnostic } from './internal/debug.js';
3
5
  import type { ConsentState, IdentityState, ResolvedConfig, ResponseEmission, ShowPromptPayload } from './internal/types.js';
@@ -65,6 +67,10 @@ export declare const UserGist: {
65
67
  readonly resumePresentation: () => void;
66
68
  readonly __internal_presentationGate: () => import("@usergist/sdk-core/mobile").PresentationGate;
67
69
  readonly initAsync: (config: SdkConfig, initialIdentity?: InitialIdentity) => Promise<IdentifyResult>;
70
+ readonly setPushSubscriptionStateHandler: typeof setPushSubscriptionStateHandler;
71
+ readonly setIdentityStateHandler: typeof setIdentityStateHandler;
72
+ readonly setSubjectTokenProvider: typeof setSubjectTokenProvider;
73
+ readonly getIdentityState: typeof getIdentityState;
68
74
  readonly identify: (userId: string, properties?: Record<string, EventPropertyValue>, subjectToken?: string) => void;
69
75
  readonly identifyAsync: (userId: string, properties?: Record<string, EventPropertyValue>, subjectToken?: string) => Promise<IdentifyResult>;
70
76
  /** Update the current user, including anonymous users. Durable and retried on reconnect. */
@@ -1 +1 @@
1
- {"version":3,"file":"UserGist.d.ts","sourceRoot":"","sources":["../src/UserGist.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UserGist.d.ts","sourceRoot":"","sources":["../src/UserGist.ts"],"names":[],"mappings":"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"}
package/dist/UserGist.js CHANGED
@@ -1,3 +1,6 @@
1
+ import { drainRevocations, hasPendingRevocations } from './internal/session-revocations.js';
2
+ import { setPushSubscriptionStateHandler, pushSubscriptionChanged } from './internal/push-subscription.js';
3
+ import { cancelIdentityRecovery, identityChanged, setIdentityStateHandler, setSubjectTokenProvider, getIdentityState } from './internal/identity-lifecycle.js';
1
4
  import { userPropertiesUpdateSchema } from '@usergist/sdk-core/mobile';
2
5
  import { hydratePushDedupe } from './internal/push-dedupe.js';
3
6
  import { REQUEST_COMMENTED_EVENT_NAME, REQUEST_COMMENT_EDITED_EVENT_NAME, REQUEST_COMMENT_DELETED_EVENT_NAME, } from '@usergist/sdk-core/mobile';
@@ -89,6 +92,20 @@ function ensureEngine(config) {
89
92
  // A host-owned invitation is not a survey start. Only automatic rendering
90
93
  // requests a session bundled with the delivery authorization.
91
94
  engine = createEngine(config, () => !surveyHandlers.onInvite);
95
+ const pushEngine = engine;
96
+ pushEngine.retryPushRegistration = async () => {
97
+ if (pushEngine.resetting)
98
+ return;
99
+ const saved = await pushEngine.storage.getJson(STORAGE_KEYS.pushDevice);
100
+ if (!saved)
101
+ return;
102
+ pushEngine.pushTokenAvailable = true;
103
+ if (pushEngine !== engine || pushEngine.resetting)
104
+ return;
105
+ pushSubscriptionChanged(pushEngine);
106
+ if (pushEngine.consent.allowsPush())
107
+ await registerPushDevice(saved.token, saved.platform, { environment: saved.environment }, true);
108
+ };
92
109
  surveyStore = createSurveyStore(config.writeKey, () => engine.identity.get());
93
110
  return engine;
94
111
  }
@@ -286,6 +303,10 @@ export const UserGist = {
286
303
  return 'rejected';
287
304
  }
288
305
  },
306
+ setPushSubscriptionStateHandler,
307
+ setIdentityStateHandler,
308
+ setSubjectTokenProvider,
309
+ getIdentityState,
289
310
  identify(userId, properties, subjectToken) {
290
311
  void UserGist.identifyAsync(userId, properties, subjectToken);
291
312
  },
@@ -296,8 +317,9 @@ export const UserGist = {
296
317
  return 'rejected';
297
318
  }
298
319
  const e = requireEngine();
320
+ const generation = e.resetGeneration;
299
321
  await ensureHydrated(e);
300
- if (e.resetting)
322
+ if (e.resetting || e.resetGeneration !== generation)
301
323
  return 'rejected';
302
324
  const identity = e.identity.get();
303
325
  const pendingIdentity = e.mutations.peek();
@@ -309,9 +331,12 @@ export const UserGist = {
309
331
  return 'rejected';
310
332
  }
311
333
  const cleanProps = e.consent.allowsAnalytics()
312
- ? asEventProps(properties)
334
+ ? (properties && Object.keys(properties).length
335
+ ? userPropertiesUpdateSchema.parse({ mutationId: generateEventId(), set: properties }).set
336
+ : undefined)
313
337
  : undefined;
314
338
  if (transition === 'already_identified' &&
339
+ (!subjectToken || subjectToken === e.subjectToken) &&
315
340
  (!cleanProps || Object.keys(cleanProps).length === 0)) {
316
341
  return 'synced';
317
342
  }
@@ -319,6 +344,7 @@ export const UserGist = {
319
344
  reportError('identify requires a server-minted subject token');
320
345
  return 'rejected';
321
346
  }
347
+ identityChanged(e, 'identifying');
322
348
  const mutationId = await e.mutations.enqueue('identify', 'essential', {
323
349
  subjectToken,
324
350
  anonymousId: identity.anonymousId,
@@ -326,7 +352,10 @@ export const UserGist = {
326
352
  ...(cleanProps ? { properties: cleanProps } : {}),
327
353
  }, `identify:${userId}`);
328
354
  const result = await flushMutations(e);
355
+ if (e.resetting || e.resetGeneration !== generation)
356
+ return 'rejected';
329
357
  if (result.permanentlyRejectedIds.has(mutationId)) {
358
+ identityChanged(e, 'rejected');
330
359
  reportError('identify was rejected by the server');
331
360
  return 'rejected';
332
361
  }
@@ -410,7 +439,7 @@ export const UserGist = {
410
439
  if (e.resetting || next.version !== e.consent.get().version)
411
440
  return false;
412
441
  if (e.lastPushToken)
413
- await UserGist.invalidatePushToken(e.lastPushToken);
442
+ await invalidatePushDevice(e.lastPushToken, true);
414
443
  await disableNativePushForConsent(e, next.version);
415
444
  }
416
445
  if (e.resetting || next.version !== e.consent.get().version)
@@ -434,6 +463,9 @@ export const UserGist = {
434
463
  reportError('transport.consent failed', err);
435
464
  return false;
436
465
  }
466
+ pushSubscriptionChanged(e);
467
+ if (next.push)
468
+ void e.retryPushRegistration?.().catch(error => reportError('push registration deferred', error));
437
469
  if (next.feedback || next.survey) {
438
470
  await refreshTargetingRules(e, true);
439
471
  }
@@ -450,10 +482,14 @@ export const UserGist = {
450
482
  reset() {
451
483
  try {
452
484
  const e = requireEngine();
453
- if (e.resetting)
454
- return resetPromise ?? Promise.resolve();
485
+ if (resetPromise)
486
+ return resetPromise;
455
487
  e.resetting = true;
488
+ identityChanged(e, 'resetting');
489
+ pushSubscriptionChanged(e);
456
490
  e.resetGeneration += 1;
491
+ e.transport.cancelAll();
492
+ cancelIdentityRecovery(e);
457
493
  e.presentation.invalidate();
458
494
  requestsCache = null;
459
495
  lastEnablePushOptions = null;
@@ -461,18 +497,15 @@ export const UserGist = {
461
497
  const operation = (async () => {
462
498
  await ensureHydrated(e);
463
499
  await syncNativePushState(e, false);
464
- await pushRegistrationQueue;
465
- if (e.lastPushToken)
466
- await UserGist.invalidatePushToken(e.lastPushToken);
467
- await UserGistPushNative.disablePush().catch(() => undefined);
500
+ void UserGistPushNative.disablePush().catch(() => undefined);
468
501
  await clearAllState(e);
469
502
  await surveyStore?.clear();
470
503
  await hydratePushDedupe(e.config.writeKey, e.identity.get().anonymousId);
471
504
  })();
472
505
  const finalized = operation
473
- .catch((err) => reportError('reset failed', err))
506
+ .then(() => { e.resetting = false; pushSubscriptionChanged(e); })
507
+ .catch((err) => { identityChanged(e, 'reset-failed'); reportError('reset failed', err); throw err; })
474
508
  .finally(() => {
475
- e.resetting = false;
476
509
  if (resetPromise === finalized)
477
510
  resetPromise = null;
478
511
  });
@@ -581,80 +614,10 @@ export const UserGist = {
581
614
  }
582
615
  },
583
616
  async registerPushToken(token, platform, opts) {
584
- try {
585
- if (!token)
586
- return;
587
- const e = requireEngine();
588
- await ensureHydrated(e);
589
- if (!e.consent.allowsPush() || e.resetting)
590
- return;
591
- const generation = e.resetGeneration;
592
- await serializePushRegistration(async () => {
593
- if (e.resetting ||
594
- generation !== e.resetGeneration ||
595
- !e.consent.allowsPush())
596
- return;
597
- const id = e.identity.get();
598
- const environment = opts?.environment ??
599
- (await UserGistPushNative.defaultEnvironment()) ??
600
- (e.config.environment === 'production' ? 'production' : 'sandbox');
601
- const registrationKey = [
602
- id.anonymousId,
603
- id.externalId ?? '',
604
- platform,
605
- environment,
606
- token,
607
- ].join(':');
608
- if (e.lastPushRegistrationKey === registrationKey &&
609
- Date.now() - e.lastPushRegistrationAt < 24 * 60 * 60_000)
610
- return;
611
- if (e.resetting ||
612
- generation !== e.resetGeneration ||
613
- !e.consent.allowsPush())
614
- return;
615
- // Persist before the request so logout can invalidate a token even when
616
- // the response is lost or the process exits after the server accepts it.
617
- e.lastPushToken = token;
618
- await e.storage.setJson(STORAGE_KEYS.pushToken, token);
619
- await e.transport.pushRegisterToken({
620
- anonymousId: id.anonymousId,
621
- externalId: id.externalId ?? null,
622
- token,
623
- platform,
624
- environment,
625
- language: undefined,
626
- timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
627
- appVersion: undefined,
628
- sdkVersion: `rn-${USERGIST_SDK_VERSION}`,
629
- optIn: true,
630
- });
631
- e.lastPushToken = token;
632
- e.lastPushRegistrationKey = registrationKey;
633
- e.lastPushRegistrationAt = Date.now();
634
- debugLog('push token registered with server');
635
- });
636
- }
637
- catch (err) {
638
- reportError('registerPushToken failed', err);
639
- }
617
+ await registerPushDevice(token, platform, opts);
640
618
  },
641
619
  async invalidatePushToken(token) {
642
- try {
643
- if (!token)
644
- return;
645
- const e = requireEngine();
646
- await ensureHydrated(e);
647
- const id = e.identity.get();
648
- e.lastPushRegistrationKey = null;
649
- e.lastPushRegistrationAt = 0;
650
- await e.transport.pushInvalidateToken({
651
- anonymousId: id.anonymousId,
652
- token,
653
- });
654
- }
655
- catch (err) {
656
- reportError('invalidatePushToken failed', err);
657
- }
620
+ await invalidatePushDevice(token);
658
621
  },
659
622
  /**
660
623
  * Re-bind the latest registered device token to a newly-identified user.
@@ -1618,4 +1581,97 @@ export const UserGist = {
1618
1581
  }
1619
1582
  },
1620
1583
  };
1584
+ /** Registration and invalidation share an ordered lane. Automatic retries may
1585
+ * consume a retained token, but must never recreate an invalidated candidate. */
1586
+ async function registerPushDevice(token, platform, opts, retry = false) {
1587
+ try {
1588
+ if (!token)
1589
+ return;
1590
+ const e = requireEngine();
1591
+ if (e.resetting)
1592
+ return;
1593
+ const generation = e.resetGeneration;
1594
+ await serializePushRegistration(async () => {
1595
+ await ensureHydrated(e);
1596
+ if (e.resetting || generation !== e.resetGeneration)
1597
+ return;
1598
+ const environment = opts?.environment ?? (await UserGistPushNative.defaultEnvironment()) ??
1599
+ (e.config.environment === 'production' ? 'production' : 'sandbox');
1600
+ if (e.resetting || generation !== e.resetGeneration)
1601
+ return;
1602
+ const descriptor = { token, platform, environment };
1603
+ const stored = await e.storage.getJson(STORAGE_KEYS.pushDevice);
1604
+ if (JSON.stringify(stored) !== JSON.stringify(descriptor)) {
1605
+ if (retry)
1606
+ return;
1607
+ await e.storage.setJsonStrict(STORAGE_KEYS.pushDevice, descriptor);
1608
+ }
1609
+ e.pushTokenAvailable = true;
1610
+ pushSubscriptionChanged(e);
1611
+ if (!e.consent.allowsPush())
1612
+ return;
1613
+ await drainRevocations(e);
1614
+ if (await hasPendingRevocations(e) || e.resetting || generation !== e.resetGeneration || !e.consent.allowsPush())
1615
+ return;
1616
+ const id = e.identity.get();
1617
+ const registrationKey = [id.anonymousId, id.externalId ?? '', platform, environment, token].join(':');
1618
+ if (e.lastPushRegistrationKey === registrationKey && Date.now() - e.lastPushRegistrationAt < 24 * 60 * 60_000)
1619
+ return;
1620
+ // Persist before delivery so logout still owns a token if its response is lost.
1621
+ e.lastPushToken = token;
1622
+ await e.storage.setJson(STORAGE_KEYS.pushToken, token);
1623
+ if (e.resetting || generation !== e.resetGeneration || !e.consent.allowsPush())
1624
+ return;
1625
+ const registration = await e.transport.pushRegisterToken({
1626
+ anonymousId: id.anonymousId, externalId: id.externalId ?? null,
1627
+ token, platform, environment, timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
1628
+ sdkVersion: `rn-${USERGIST_SDK_VERSION}`, optIn: true,
1629
+ });
1630
+ if (e.resetting || generation !== e.resetGeneration || !e.consent.allowsPush())
1631
+ return;
1632
+ if (!(registration && typeof registration === 'object' && 'registered' in registration && registration.registered === true)) {
1633
+ pushSubscriptionChanged(e);
1634
+ return;
1635
+ }
1636
+ e.lastPushRegistrationKey = registrationKey;
1637
+ e.lastPushRegistrationAt = Date.now();
1638
+ pushSubscriptionChanged(e);
1639
+ debugLog('push token registered with server');
1640
+ });
1641
+ }
1642
+ catch (err) {
1643
+ reportError('registerPushToken failed', err);
1644
+ }
1645
+ }
1646
+ async function invalidatePushDevice(token, retainDevice = false) {
1647
+ try {
1648
+ if (!token)
1649
+ return;
1650
+ const e = requireEngine();
1651
+ const generation = e.resetGeneration;
1652
+ await serializePushRegistration(async () => {
1653
+ await ensureHydrated(e);
1654
+ if (e.resetting || generation !== e.resetGeneration)
1655
+ return;
1656
+ const saved = await e.storage.getJson(STORAGE_KEYS.pushDevice);
1657
+ if (saved?.token === token) {
1658
+ // Retire the automatic retry candidate before invalidating it remotely.
1659
+ if (!retainDevice)
1660
+ await e.storage.setJsonStrict(STORAGE_KEYS.pushDevice, null);
1661
+ e.pushTokenAvailable = retainDevice;
1662
+ e.lastPushRegistrationKey = null;
1663
+ e.lastPushRegistrationAt = 0;
1664
+ }
1665
+ if (e.lastPushToken === token) {
1666
+ await e.storage.setJsonStrict(STORAGE_KEYS.pushToken, null);
1667
+ e.lastPushToken = null;
1668
+ }
1669
+ pushSubscriptionChanged(e);
1670
+ await e.transport.pushInvalidateToken({ anonymousId: e.identity.get().anonymousId, token });
1671
+ });
1672
+ }
1673
+ catch (err) {
1674
+ reportError('invalidatePushToken failed', err);
1675
+ }
1676
+ }
1621
1677
  //# sourceMappingURL=UserGist.js.map