@monterosa/sdk-identify-kit 2.0.0-rc.4 → 2.0.0-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +109 -168
- package/dist/bridge.d.ts +1 -1
- package/dist/credentials_store.d.ts +1 -1
- package/dist/index.cjs +100 -148
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +100 -148
- package/dist/index.js.map +1 -1
- package/dist/sdk-identify-kit.d.ts +500 -0
- package/dist/tsdoc-metadata.json +11 -0
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -301,7 +301,7 @@ class LoginPolicyStore extends Emitter {
|
|
|
301
301
|
* More details on the license can be found at https://www.monterosa.co/sdk/license
|
|
302
302
|
*/
|
|
303
303
|
/**
|
|
304
|
-
* Root-owned credentials
|
|
304
|
+
* Root-owned credentials store.
|
|
305
305
|
*
|
|
306
306
|
* Single source of truth at the root of an integration; an internal
|
|
307
307
|
* mirror at every other level, kept in sync via `Login` / `Logout`
|
|
@@ -373,26 +373,18 @@ function getLoginPolicy() {
|
|
|
373
373
|
return loginPolicyStore.policy;
|
|
374
374
|
}
|
|
375
375
|
/**
|
|
376
|
-
* Set the
|
|
376
|
+
* Set the login policy.
|
|
377
377
|
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
*
|
|
378
|
+
* - `'auto'`: the SDK automatically logs the user in whenever
|
|
379
|
+
* credentials are available.
|
|
380
|
+
* - `'disabled'`: credentials are tracked but no automatic login is
|
|
381
|
+
* attempted.
|
|
381
382
|
*
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
*
|
|
385
|
-
* `Login` / `Logout` broadcasts; it just doesn't attempt Enmasse
|
|
386
|
-
* validation against them.
|
|
383
|
+
* Each level of a multi-level integration owns its own policy; the
|
|
384
|
+
* value is never propagated to embedded experiences. Idempotent:
|
|
385
|
+
* setting the same policy is a no-op.
|
|
387
386
|
*
|
|
388
|
-
*
|
|
389
|
-
* for every existing identify so that any in-flight session is picked
|
|
390
|
-
* up.
|
|
391
|
-
*
|
|
392
|
-
* Idempotent: setting the same policy that's already in effect is a
|
|
393
|
-
* no-op.
|
|
394
|
-
*
|
|
395
|
-
* @param policy - `'auto'` to enable auto-login, `'disabled'` to opt out.
|
|
387
|
+
* @param policy - `'auto'` or `'disabled'`.
|
|
396
388
|
*/
|
|
397
389
|
function setLoginPolicy(policy) {
|
|
398
390
|
if (loginPolicyStore.policy === policy) {
|
|
@@ -402,13 +394,12 @@ function setLoginPolicy(policy) {
|
|
|
402
394
|
if (policy !== 'auto') {
|
|
403
395
|
return;
|
|
404
396
|
}
|
|
405
|
-
// On transition to 'auto': if
|
|
406
|
-
//
|
|
407
|
-
//
|
|
408
|
-
//
|
|
409
|
-
//
|
|
410
|
-
//
|
|
411
|
-
// policy.
|
|
397
|
+
// On transition to 'auto': if credentials are currently set (typical
|
|
398
|
+
// after the non-root module-load pull, or after a setCredentials at
|
|
399
|
+
// the root, or after an upstream Login broadcast has cascaded down),
|
|
400
|
+
// enqueue a login task for each existing identify. If no credentials
|
|
401
|
+
// are set, do nothing — a future credentials arrival via `applyLogin`
|
|
402
|
+
// will trigger the login under this new policy.
|
|
412
403
|
const { credentials } = credentialsStore;
|
|
413
404
|
if (credentials === null) {
|
|
414
405
|
return;
|
|
@@ -602,13 +593,15 @@ function enqueueLogout(identify) {
|
|
|
602
593
|
taskQueue.enqueue(() => logoutTask(identify));
|
|
603
594
|
}
|
|
604
595
|
/**
|
|
605
|
-
* Apply new credentials at this level: update the
|
|
606
|
-
* `loginTask` for every existing identify on the null-to-set
|
|
607
|
-
* and broadcast `Login` downstream to every embedded
|
|
596
|
+
* Apply new credentials at this level: update the current credentials,
|
|
597
|
+
* enqueue a `loginTask` for every existing identify on the null-to-set
|
|
598
|
+
* transition, and broadcast `Login` downstream to every embedded
|
|
599
|
+
* experience.
|
|
608
600
|
*
|
|
609
|
-
* Idempotent on token refresh: re-setting
|
|
610
|
-
* the value and broadcasts, but does not re-enqueue
|
|
611
|
-
* `loginTask` would short-circuit on
|
|
601
|
+
* Idempotent on token refresh: re-setting when credentials are already
|
|
602
|
+
* present updates the value and broadcasts, but does not re-enqueue
|
|
603
|
+
* logins (their `loginTask` would short-circuit on
|
|
604
|
+
* `state === 'logged_in'` anyway).
|
|
612
605
|
*
|
|
613
606
|
* @internal
|
|
614
607
|
*/
|
|
@@ -625,10 +618,10 @@ function applyLogin(credentials) {
|
|
|
625
618
|
}
|
|
626
619
|
}
|
|
627
620
|
/**
|
|
628
|
-
* Clear credentials at this level:
|
|
629
|
-
* `logoutTask` for every existing identify on the
|
|
630
|
-
* transition, and broadcast `Logout` downstream to every
|
|
631
|
-
* experience.
|
|
621
|
+
* Clear credentials at this level: clear the current credentials,
|
|
622
|
+
* enqueue a `logoutTask` for every existing identify on the
|
|
623
|
+
* set-to-null transition, and broadcast `Logout` downstream to every
|
|
624
|
+
* embedded experience.
|
|
632
625
|
*
|
|
633
626
|
* @internal
|
|
634
627
|
*/
|
|
@@ -651,11 +644,11 @@ function applyLogout() {
|
|
|
651
644
|
* `loginPolicy` — token presence is the customer-side sign-in state and
|
|
652
645
|
* must mirror upstream whether or not we choose to validate against
|
|
653
646
|
* Enmasse. Best-effort: a missing or non-identify-kit parent silently
|
|
654
|
-
* resolves with no
|
|
647
|
+
* resolves with no change to the current credentials.
|
|
655
648
|
*
|
|
656
|
-
* Uses {@link applyLogin} so the
|
|
657
|
-
*
|
|
658
|
-
*
|
|
649
|
+
* Uses {@link applyLogin} so the update cascades downstream to this
|
|
650
|
+
* level's own embedded experiences and per-identify loginTasks are
|
|
651
|
+
* enqueued under `loginPolicy === 'auto'`.
|
|
659
652
|
*
|
|
660
653
|
* @internal
|
|
661
654
|
*/
|
|
@@ -710,7 +703,10 @@ function getIdentify(sdkOrOptions, options) {
|
|
|
710
703
|
return identify;
|
|
711
704
|
}
|
|
712
705
|
/**
|
|
713
|
-
*
|
|
706
|
+
* Request a user login.
|
|
707
|
+
*
|
|
708
|
+
* When called from an embedded experience, the request is relayed to
|
|
709
|
+
* the parent application — the host that owns the auth UI handles it.
|
|
714
710
|
*
|
|
715
711
|
* @example
|
|
716
712
|
* ```javascript
|
|
@@ -721,20 +717,14 @@ function getIdentify(sdkOrOptions, options) {
|
|
|
721
717
|
*
|
|
722
718
|
* try {
|
|
723
719
|
* await requestLogin();
|
|
724
|
-
*
|
|
725
720
|
* console.log('Login request successful');
|
|
726
721
|
* } catch (err) {
|
|
727
722
|
* console.error('Error requesting login:', err.message)
|
|
728
723
|
* }
|
|
729
724
|
* ```
|
|
730
725
|
*
|
|
731
|
-
* @
|
|
732
|
-
*
|
|
733
|
-
* the Monterosa SDK, the function delegates to the parent app
|
|
734
|
-
* to handle the login process.
|
|
735
|
-
*
|
|
736
|
-
* @returns A Promise that resolves with `void` when the login request
|
|
737
|
-
* is completed.
|
|
726
|
+
* @returns A Promise that resolves once the login request has been
|
|
727
|
+
* delivered.
|
|
738
728
|
*/
|
|
739
729
|
async function requestLogin() {
|
|
740
730
|
if (getParentApplication() !== null) {
|
|
@@ -744,16 +734,14 @@ async function requestLogin() {
|
|
|
744
734
|
requestsEmitter.emit(IdentifyEvent.LoginRequested);
|
|
745
735
|
}
|
|
746
736
|
/**
|
|
747
|
-
* Read the current credentials
|
|
748
|
-
* called from an embedded experience.
|
|
737
|
+
* Read the current credentials.
|
|
749
738
|
*
|
|
750
|
-
*
|
|
751
|
-
*
|
|
752
|
-
*
|
|
753
|
-
* authoritative value rather than a possibly-stale local mirror.
|
|
739
|
+
* When called from an embedded experience, fetches the credentials
|
|
740
|
+
* from the parent application so the caller always sees the
|
|
741
|
+
* authoritative value.
|
|
754
742
|
*
|
|
755
|
-
* @returns A Promise that resolves to the current credentials, or
|
|
756
|
-
* if none are set.
|
|
743
|
+
* @returns A Promise that resolves to the current credentials, or
|
|
744
|
+
* `null` if none are set.
|
|
757
745
|
*/
|
|
758
746
|
async function getCredentials() {
|
|
759
747
|
if (getParentApplication() === null) {
|
|
@@ -762,7 +750,10 @@ async function getCredentials() {
|
|
|
762
750
|
return sendParentRequest(IdentifyAction.GetCredentials);
|
|
763
751
|
}
|
|
764
752
|
/**
|
|
765
|
-
*
|
|
753
|
+
* Request a user logout.
|
|
754
|
+
*
|
|
755
|
+
* When called from an embedded experience, the request is relayed to
|
|
756
|
+
* the parent application — the host that owns the auth UI handles it.
|
|
766
757
|
*
|
|
767
758
|
* @example
|
|
768
759
|
* ```javascript
|
|
@@ -773,20 +764,14 @@ async function getCredentials() {
|
|
|
773
764
|
*
|
|
774
765
|
* try {
|
|
775
766
|
* await requestLogout();
|
|
776
|
-
*
|
|
777
767
|
* console.log('Logout request successful');
|
|
778
768
|
* } catch (err) {
|
|
779
769
|
* console.error('Error requesting logout:', err.message)
|
|
780
770
|
* }
|
|
781
771
|
* ```
|
|
782
772
|
*
|
|
783
|
-
* @
|
|
784
|
-
*
|
|
785
|
-
* the Monterosa SDK, the function delegates to the parent app
|
|
786
|
-
* to handle the logout process.
|
|
787
|
-
*
|
|
788
|
-
* @returns A Promise that resolves with `void` when the logout request
|
|
789
|
-
* is completed.
|
|
773
|
+
* @returns A Promise that resolves once the logout request has been
|
|
774
|
+
* delivered.
|
|
790
775
|
*/
|
|
791
776
|
async function requestLogout() {
|
|
792
777
|
if (getParentApplication() !== null) {
|
|
@@ -822,6 +807,8 @@ async function getSessionSignature(identify, credentials) {
|
|
|
822
807
|
return signature;
|
|
823
808
|
}
|
|
824
809
|
/**
|
|
810
|
+
* @internal
|
|
811
|
+
*
|
|
825
812
|
* A memoized version of the `getSessionSignature` function. Memo key is
|
|
826
813
|
* the credentials token, so both leaf-side and bridge-side callers share
|
|
827
814
|
* the same cache for the same token.
|
|
@@ -831,12 +818,10 @@ const getSessionSignatureMemoized = memoizePromise(getSessionSignature, (identif
|
|
|
831
818
|
clearOnReject: true,
|
|
832
819
|
});
|
|
833
820
|
/**
|
|
834
|
-
*
|
|
821
|
+
* Fetch user data for the given credentials.
|
|
835
822
|
*
|
|
836
|
-
* Credentials are required explicitly
|
|
837
|
-
*
|
|
838
|
-
* `Credentials` value via {@link getCredentials} or the
|
|
839
|
-
* {@link onCredentialsUpdated} callback.
|
|
823
|
+
* Credentials are required explicitly. Obtain a value via
|
|
824
|
+
* {@link getCredentials} or the {@link onCredentialsUpdated} callback.
|
|
840
825
|
*
|
|
841
826
|
* @example
|
|
842
827
|
* ```javascript
|
|
@@ -859,16 +844,13 @@ const getSessionSignatureMemoized = memoizePromise(getSessionSignature, (identif
|
|
|
859
844
|
* ```
|
|
860
845
|
*
|
|
861
846
|
* @remarks
|
|
862
|
-
* Cached
|
|
863
|
-
*
|
|
864
|
-
*
|
|
865
|
-
* @param identify -
|
|
866
|
-
*
|
|
867
|
-
* @
|
|
868
|
-
*
|
|
869
|
-
* @returns A Promise that resolves to a key-value object representing
|
|
870
|
-
* user data. The structure and content of the user data object depend
|
|
871
|
-
* on the identify service provider and may vary.
|
|
847
|
+
* Cached after the first successful fetch and reset when credentials
|
|
848
|
+
* are cleared.
|
|
849
|
+
*
|
|
850
|
+
* @param identify - The IdentifyKit instance.
|
|
851
|
+
* @param credentials - The user's authentication credentials.
|
|
852
|
+
* @returns A Promise that resolves to a key-value object of user data.
|
|
853
|
+
* The structure depends on the identify service provider.
|
|
872
854
|
*/
|
|
873
855
|
async function getUserData(identify, credentials) {
|
|
874
856
|
if (identify.userData !== null) {
|
|
@@ -880,7 +862,12 @@ async function getUserData(identify, credentials) {
|
|
|
880
862
|
return data;
|
|
881
863
|
}
|
|
882
864
|
/**
|
|
883
|
-
*
|
|
865
|
+
* Set the user's authentication credentials.
|
|
866
|
+
*
|
|
867
|
+
* The credentials become the active credentials for the entire
|
|
868
|
+
* integration. When called from an embedded experience, the call is
|
|
869
|
+
* relayed to the parent application so that every level of the
|
|
870
|
+
* integration sees the new value.
|
|
884
871
|
*
|
|
885
872
|
* @example
|
|
886
873
|
* ```javascript
|
|
@@ -892,18 +879,9 @@ async function getUserData(identify, credentials) {
|
|
|
892
879
|
* await setCredentials({ token: 'abc123' });
|
|
893
880
|
* ```
|
|
894
881
|
*
|
|
895
|
-
* @
|
|
896
|
-
*
|
|
897
|
-
*
|
|
898
|
-
* - When called from an embedded experience, the call is relayed
|
|
899
|
-
* upstream via the `SetCredentials` wire action. The credentials are
|
|
900
|
-
* ultimately applied at the root and propagate back down via the
|
|
901
|
-
* cascading `Login` broadcast.
|
|
902
|
-
*
|
|
903
|
-
* @param credentials - An object representing the user's authentication
|
|
904
|
-
* credentials.
|
|
905
|
-
* @returns A Promise that resolves to `void` once the credentials have
|
|
906
|
-
* been written (root) or the upstream relay has completed (non-root).
|
|
882
|
+
* @param credentials - The user's authentication credentials.
|
|
883
|
+
* @returns A Promise that resolves once the credentials have been
|
|
884
|
+
* applied.
|
|
907
885
|
*/
|
|
908
886
|
async function setCredentials(credentials) {
|
|
909
887
|
if (getParentApplication() !== null) {
|
|
@@ -913,7 +891,11 @@ async function setCredentials(credentials) {
|
|
|
913
891
|
applyLogin(credentials);
|
|
914
892
|
}
|
|
915
893
|
/**
|
|
916
|
-
*
|
|
894
|
+
* Clear the user's authentication credentials.
|
|
895
|
+
*
|
|
896
|
+
* When called from an embedded experience, the call is relayed to the
|
|
897
|
+
* parent application so that every level of the integration is
|
|
898
|
+
* cleared.
|
|
917
899
|
*
|
|
918
900
|
* @example
|
|
919
901
|
* ```javascript
|
|
@@ -925,16 +907,8 @@ async function setCredentials(credentials) {
|
|
|
925
907
|
* await clearCredentials();
|
|
926
908
|
* ```
|
|
927
909
|
*
|
|
928
|
-
* @
|
|
929
|
-
*
|
|
930
|
-
* a `Logout` broadcast is sent to every embedded experience.
|
|
931
|
-
* - When called from an embedded experience, the call is relayed
|
|
932
|
-
* upstream via the `ClearCredentials` wire action. The slot is
|
|
933
|
-
* cleared at the root and the cascading `Logout` broadcast propagates
|
|
934
|
-
* back down.
|
|
935
|
-
*
|
|
936
|
-
* @returns A Promise that resolves to `void` once the slot has been
|
|
937
|
-
* cleared (root) or the upstream relay has completed (non-root).
|
|
910
|
+
* @returns A Promise that resolves once the credentials have been
|
|
911
|
+
* cleared.
|
|
938
912
|
*/
|
|
939
913
|
async function clearCredentials() {
|
|
940
914
|
if (getParentApplication() !== null) {
|
|
@@ -944,8 +918,7 @@ async function clearCredentials() {
|
|
|
944
918
|
applyLogout();
|
|
945
919
|
}
|
|
946
920
|
/**
|
|
947
|
-
*
|
|
948
|
-
* object associated with the `IdentifyKit` instance is updated.
|
|
921
|
+
* Register a callback for `LoginState` updates on the given identify.
|
|
949
922
|
*
|
|
950
923
|
* @example
|
|
951
924
|
* ```javascript
|
|
@@ -959,24 +932,17 @@ async function clearCredentials() {
|
|
|
959
932
|
* const unsubscribe = onStateUpdated(identify, (state) => {
|
|
960
933
|
* console.log("State updated:", state);
|
|
961
934
|
* });
|
|
962
|
-
*
|
|
963
|
-
* // Call unsubscribe() to unregister the callback function
|
|
964
|
-
* // unsubscribe();
|
|
965
935
|
* ```
|
|
966
936
|
*
|
|
967
|
-
* @param identify -
|
|
968
|
-
*
|
|
969
|
-
* @
|
|
970
|
-
* called with the updated `LoginState` object as its only argument.
|
|
971
|
-
* @returns An `Unsubscribe` function that can be called to unregister
|
|
972
|
-
* the callback function.
|
|
937
|
+
* @param identify - The IdentifyKit instance.
|
|
938
|
+
* @param callback - Called with the updated `LoginState`.
|
|
939
|
+
* @returns An `Unsubscribe` function.
|
|
973
940
|
*/
|
|
974
941
|
function onStateUpdated(identify, callback) {
|
|
975
942
|
return subscribe(identify, IdentifyEvent.StateUpdated, callback);
|
|
976
943
|
}
|
|
977
944
|
/**
|
|
978
|
-
*
|
|
979
|
-
* credentials slot is updated.
|
|
945
|
+
* Register a callback for updates to the current credentials.
|
|
980
946
|
*
|
|
981
947
|
* @example
|
|
982
948
|
* ```javascript
|
|
@@ -992,24 +958,20 @@ function onStateUpdated(identify, callback) {
|
|
|
992
958
|
* console.log("Credentials cleared.");
|
|
993
959
|
* }
|
|
994
960
|
* });
|
|
995
|
-
*
|
|
996
|
-
* // Call unsubscribe() to unregister the callback function
|
|
997
|
-
* // unsubscribe();
|
|
998
961
|
* ```
|
|
999
962
|
*
|
|
1000
|
-
* @param callback -
|
|
1001
|
-
*
|
|
1002
|
-
*
|
|
1003
|
-
* been cleared.
|
|
1004
|
-
* @returns An `Unsubscribe` function that can be called to unregister
|
|
1005
|
-
* the callback function.
|
|
963
|
+
* @param callback - Called with the updated `Credentials`, or `null`
|
|
964
|
+
* when credentials are cleared.
|
|
965
|
+
* @returns An `Unsubscribe` function.
|
|
1006
966
|
*/
|
|
1007
967
|
function onCredentialsUpdated(callback) {
|
|
1008
968
|
return credentialsStore.subscribe(callback);
|
|
1009
969
|
}
|
|
1010
970
|
/**
|
|
1011
|
-
*
|
|
1012
|
-
*
|
|
971
|
+
* Register a callback for login requests.
|
|
972
|
+
*
|
|
973
|
+
* Fires when {@link requestLogin} is called at this level — whether by
|
|
974
|
+
* local code or relayed up from an embedded experience.
|
|
1013
975
|
*
|
|
1014
976
|
* @example
|
|
1015
977
|
* ```javascript
|
|
@@ -1021,22 +983,19 @@ function onCredentialsUpdated(callback) {
|
|
|
1021
983
|
* const unsubscribe = onLoginRequestedByExperience(() => {
|
|
1022
984
|
* showLoginForm();
|
|
1023
985
|
* });
|
|
1024
|
-
*
|
|
1025
|
-
* // Call unsubscribe() to unregister the callback function
|
|
1026
|
-
* // unsubscribe();
|
|
1027
986
|
* ```
|
|
1028
987
|
*
|
|
1029
|
-
* @param callback -
|
|
1030
|
-
*
|
|
1031
|
-
* @returns An `Unsubscribe` function that can be called to unregister
|
|
1032
|
-
* the callback function.
|
|
988
|
+
* @param callback - Called when a login is requested.
|
|
989
|
+
* @returns An `Unsubscribe` function.
|
|
1033
990
|
*/
|
|
1034
991
|
function onLoginRequestedByExperience(callback) {
|
|
1035
992
|
return subscribe(requestsEmitter, IdentifyEvent.LoginRequested, callback);
|
|
1036
993
|
}
|
|
1037
994
|
/**
|
|
1038
|
-
*
|
|
1039
|
-
*
|
|
995
|
+
* Register a callback for logout requests.
|
|
996
|
+
*
|
|
997
|
+
* Fires when {@link requestLogout} is called at this level — whether
|
|
998
|
+
* by local code or relayed up from an embedded experience.
|
|
1040
999
|
*
|
|
1041
1000
|
* @example
|
|
1042
1001
|
* ```javascript
|
|
@@ -1046,24 +1005,17 @@ function onLoginRequestedByExperience(callback) {
|
|
|
1046
1005
|
* configure({ host: '...', projectId: '...' });
|
|
1047
1006
|
*
|
|
1048
1007
|
* const unsubscribe = onLogoutRequestedByExperience(() => {
|
|
1049
|
-
* // logout
|
|
1050
|
-
* // perform logout from Auth service
|
|
1008
|
+
* // perform logout from auth service
|
|
1051
1009
|
* });
|
|
1052
|
-
*
|
|
1053
|
-
* // Call unsubscribe() to unregister the callback function
|
|
1054
|
-
* // unsubscribe();
|
|
1055
1010
|
* ```
|
|
1056
1011
|
*
|
|
1057
|
-
* @param callback -
|
|
1058
|
-
*
|
|
1059
|
-
* @returns An `Unsubscribe` function that can be called to unregister
|
|
1060
|
-
* the callback function.
|
|
1012
|
+
* @param callback - Called when a logout is requested.
|
|
1013
|
+
* @returns An `Unsubscribe` function.
|
|
1061
1014
|
*/
|
|
1062
1015
|
function onLogoutRequestedByExperience(callback) {
|
|
1063
1016
|
return subscribe(requestsEmitter, IdentifyEvent.LogoutRequested, callback);
|
|
1064
1017
|
}
|
|
1065
1018
|
/**
|
|
1066
|
-
*
|
|
1067
1019
|
* @internal
|
|
1068
1020
|
*/
|
|
1069
1021
|
async function watchConnectionStatus(identify) {
|
|
@@ -1108,7 +1060,7 @@ async function watchConnectionStatus(identify) {
|
|
|
1108
1060
|
*/
|
|
1109
1061
|
/**
|
|
1110
1062
|
* Process an incoming `Login` / `Logout` broadcast from the parent
|
|
1111
|
-
* application. Updates the local credentials
|
|
1063
|
+
* application. Updates the local current credentials, enqueues login/logout
|
|
1112
1064
|
* for every existing identify, and forwards the broadcast downstream to
|
|
1113
1065
|
* this level's own embedded experiences — the mechanism that cascades a
|
|
1114
1066
|
* root-level `setCredentials` through every nested experience.
|