@monterosa/sdk-identify-kit 2.0.0-rc.3 → 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/index.cjs CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var sdkCore = require('@monterosa/sdk-core');
6
5
  var sdkUtil = require('@monterosa/sdk-util');
7
6
  var sdkLauncherKit = require('@monterosa/sdk-launcher-kit');
7
+ var sdkCore = require('@monterosa/sdk-core');
8
8
  var sdkConnectKit = require('@monterosa/sdk-connect-kit');
9
9
  var sdkInteractInterop = require('@monterosa/sdk-interact-interop');
10
10
 
@@ -24,10 +24,8 @@ var IdentifyEvent;
24
24
  IdentifyEvent["StateUpdated"] = "state_updated";
25
25
  IdentifyEvent["LoginRequested"] = "login_requested";
26
26
  IdentifyEvent["LogoutRequested"] = "logout_requested";
27
- IdentifyEvent["SignatureUpdated"] = "signature_updated";
28
- IdentifyEvent["UserdataUpdated"] = "userdata_updated";
29
27
  IdentifyEvent["CredentialsUpdated"] = "credentials_updated";
30
- IdentifyEvent["EnmasseLogin"] = "enmasse_login";
28
+ IdentifyEvent["LoginPolicyUpdated"] = "login_policy_updated";
31
29
  })(IdentifyEvent || (IdentifyEvent = {}));
32
30
  /**
33
31
  * Defines a set of error codes that may be encountered when using the
@@ -40,8 +38,6 @@ var IdentifyEvent;
40
38
  * } catch (err) {
41
39
  * if (err.code === IdentifyError.NoCredentials) {
42
40
  * // handle missing credentials error
43
- * } else if (err.code === IdentifyError.NotInitialised) {
44
- * // handle initialization error
45
41
  * } else {
46
42
  * // handle other error types
47
43
  * }
@@ -71,10 +67,6 @@ exports.IdentifyError = void 0;
71
67
  * or have expired.
72
68
  */
73
69
  IdentifyError["NoCredentials"] = "no_credentials";
74
- /**
75
- * Indicates the IdentifyKit has not been initialised properly.
76
- */
77
- IdentifyError["NotInitialised"] = "not_initialised";
78
70
  /**
79
71
  * Indicates an error occurred in the parent app.
80
72
  */
@@ -99,7 +91,6 @@ const IdentifyErrorMessages = {
99
91
  [exports.IdentifyError.ExtensionApiError]: (error) => `Identify extension API returned an error: ${error}`,
100
92
  [exports.IdentifyError.ExtensionNotSetup]: () => 'Identify extension is not set up for this project',
101
93
  [exports.IdentifyError.NoCredentials]: () => 'Identify credentials are not set',
102
- [exports.IdentifyError.NotInitialised]: () => 'Identify instance is not initialised',
103
94
  [exports.IdentifyError.ParentAppError]: (error) => `Parent application error: ${error}`,
104
95
  [exports.IdentifyError.UnexpectedState]: (state) => `Unexpected LoginState: ${state}`,
105
96
  [exports.IdentifyError.NoParentApplication]: () => 'No parent application available for delegation',
@@ -111,14 +102,9 @@ var IdentifyAction;
111
102
  IdentifyAction["Logout"] = "identifyLogout";
112
103
  IdentifyAction["RequestLogin"] = "identifyRequestLogin";
113
104
  IdentifyAction["RequestLogout"] = "identifyRequestLogout";
114
- IdentifyAction["GetUserData"] = "identifyGetUserData";
115
- IdentifyAction["GetSessionSignature"] = "identifyGetSessionSignature";
105
+ IdentifyAction["GetCredentials"] = "identifyGetCredentials";
116
106
  IdentifyAction["SetCredentials"] = "identifySetCredentials";
117
107
  IdentifyAction["ClearCredentials"] = "identifyClearCredentials";
118
- IdentifyAction["OnStateUpdated"] = "identifyOnStateUpdated";
119
- IdentifyAction["OnCredentialsUpdated"] = "identifyOnCredentialsUpdated";
120
- IdentifyAction["OnUserDataUpdated"] = "identifyOnUserDataUpdated";
121
- IdentifyAction["OnSessionSignatureUpdated"] = "identifyOnSessionSignatureUpdated";
122
108
  })(IdentifyAction || (IdentifyAction = {}));
123
109
 
124
110
  /**
@@ -145,13 +131,12 @@ class Identify extends sdkUtil.Emitter {
145
131
  super();
146
132
  this.sdk = sdk;
147
133
  this.wasLoggedIn = false;
148
- this._credentials = null;
149
134
  this._signature = null;
150
135
  this._userData = null;
151
136
  this._state = {
152
137
  state: 'logged_out',
153
138
  };
154
- this._options = Object.assign({ strategy: 'email', deviceId: sdkCore.getDeviceId(), version: 1, loginPolicy: 'disabled' }, options);
139
+ this._options = Object.assign({ strategy: 'email', version: 1 }, options);
155
140
  }
156
141
  static async fetchIdentifyHost(host, projectId) {
157
142
  var _a, _b;
@@ -174,12 +159,13 @@ class Identify extends sdkUtil.Emitter {
174
159
  case 'logged_in':
175
160
  this.wasLoggedIn = true;
176
161
  break;
177
- case 'logged_out':
178
162
  case 'error':
179
163
  this.wasLoggedIn = false;
180
164
  break;
165
+ case 'logged_out':
181
166
  case 'pending':
182
- // preserve wasLoggedIn value during transitional state
167
+ // preserve wasLoggedIn these states reflect transient transport
168
+ // state, not a deliberate logout (credentials are the gate for that)
183
169
  break;
184
170
  default: {
185
171
  // Exhaustiveness check: TypeScript errors if a new state is added
@@ -207,53 +193,29 @@ class Identify extends sdkUtil.Emitter {
207
193
  this.signature = null;
208
194
  }, SIGNATURE_TTL);
209
195
  }
210
- this.emit(IdentifyEvent.SignatureUpdated, this.signature);
211
196
  }
212
197
  get signature() {
213
198
  return this._signature;
214
199
  }
215
- set credentials(credentials) {
216
- if (this._credentials === credentials) {
217
- return;
218
- }
219
- this._credentials = credentials;
220
- this.emit(IdentifyEvent.CredentialsUpdated, credentials);
221
- }
222
- get credentials() {
223
- return this._credentials;
224
- }
225
200
  set userData(data) {
226
201
  if (this._userData === data) {
227
202
  return;
228
203
  }
229
204
  this._userData = data;
230
- clearTimeout(this.userDataExpireTimeout);
231
- this.emit(IdentifyEvent.UserdataUpdated, data);
232
205
  }
233
206
  get userData() {
234
207
  return this._userData;
235
208
  }
236
- get shouldLoginOnReconnect() {
237
- return (this.wasLoggedIn &&
238
- this.options.loginPolicy === 'auto' &&
239
- this.credentials !== null);
240
- }
241
- reset() {
242
- this.credentials = null;
243
- this.userData = null;
244
- this.signature = null;
245
- this.wasLoggedIn = false;
246
- }
247
209
  async getUrl(path = '') {
248
- const { options: { host, projectId }, } = this.sdk;
210
+ const { host, projectId } = this.sdk.options;
249
211
  if (this.host === undefined) {
250
212
  this.host = await Identify.fetchIdentifyHost(host, projectId);
251
213
  }
252
214
  const url = new URL(this.host);
253
- const { version, deviceId, strategy, provider } = this._options;
215
+ const { version, strategy, provider } = this._options;
254
216
  url.pathname = `/v${version}${path}`;
255
217
  url.searchParams.set('projectId', projectId);
256
- url.searchParams.set('deviceId', deviceId);
218
+ url.searchParams.set('deviceId', sdkCore.getDeviceId());
257
219
  url.searchParams.set('strategy', strategy);
258
220
  if (provider !== undefined) {
259
221
  url.searchParams.set('provider', provider);
@@ -288,6 +250,101 @@ function deleteExperience(experience) {
288
250
  }
289
251
  }
290
252
 
253
+ /**
254
+ * @license
255
+ * @monterosa/sdk-identify-kit
256
+ *
257
+ * Copyright © 2026 Monterosa Productions Limited. All rights reserved.
258
+ *
259
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
260
+ */
261
+ /**
262
+ * Locally-owned login policy.
263
+ *
264
+ * Defaults to `'disabled'`. Set via the public `setLoginPolicy`. Never
265
+ * propagated across the wire — each level owns its own policy.
266
+ *
267
+ * @internal
268
+ */
269
+ class LoginPolicyStore extends sdkUtil.Emitter {
270
+ constructor() {
271
+ super();
272
+ this._policy = 'disabled';
273
+ }
274
+ static getInstance() {
275
+ if (!LoginPolicyStore.instance) {
276
+ LoginPolicyStore.instance = new LoginPolicyStore();
277
+ }
278
+ return LoginPolicyStore.instance;
279
+ }
280
+ get policy() {
281
+ return this._policy;
282
+ }
283
+ set policy(next) {
284
+ if (this._policy === next) {
285
+ return;
286
+ }
287
+ this._policy = next;
288
+ this.emit(IdentifyEvent.LoginPolicyUpdated, next);
289
+ }
290
+ subscribe(handler) {
291
+ return sdkUtil.subscribe(this, IdentifyEvent.LoginPolicyUpdated, handler);
292
+ }
293
+ reset() {
294
+ this._policy = 'disabled';
295
+ this.off(IdentifyEvent.LoginPolicyUpdated);
296
+ }
297
+ }
298
+
299
+ /**
300
+ * @license
301
+ * @monterosa/sdk-identify-kit
302
+ *
303
+ * Copyright © 2026 Monterosa Productions Limited. All rights reserved.
304
+ *
305
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
306
+ */
307
+ /**
308
+ * Root-owned credentials store.
309
+ *
310
+ * Single source of truth at the root of an integration; an internal
311
+ * mirror at every other level, kept in sync via `Login` / `Logout`
312
+ * broadcasts. Not exposed publicly — public access flows through
313
+ * `setCredentials` / `getCredentials` / `clearCredentials` and
314
+ * `onCredentialsUpdated`.
315
+ *
316
+ * @internal
317
+ */
318
+ class CredentialsStore extends sdkUtil.Emitter {
319
+ constructor() {
320
+ super();
321
+ this._credentials = null;
322
+ }
323
+ static getInstance() {
324
+ if (!CredentialsStore.instance) {
325
+ CredentialsStore.instance = new CredentialsStore();
326
+ }
327
+ return CredentialsStore.instance;
328
+ }
329
+ get credentials() {
330
+ return this._credentials;
331
+ }
332
+ set credentials(next) {
333
+ if (this._credentials === next) {
334
+ return;
335
+ }
336
+ this._credentials = next;
337
+ this.emit(IdentifyEvent.CredentialsUpdated, next);
338
+ }
339
+ subscribe(handler) {
340
+ return sdkUtil.subscribe(this, IdentifyEvent.CredentialsUpdated, handler);
341
+ }
342
+ reset() {
343
+ this._credentials = null;
344
+ this.off(IdentifyEvent.CredentialsUpdated);
345
+ }
346
+ }
347
+
291
348
  /**
292
349
  * @license
293
350
  * identify-kit
@@ -296,8 +353,78 @@ function deleteExperience(experience) {
296
353
  *
297
354
  * More details on the license can be found at https://www.monterosa.co/sdk/license
298
355
  */
356
+ const loginPolicyStore = LoginPolicyStore.getInstance();
357
+ const credentialsStore = CredentialsStore.getInstance();
358
+ /**
359
+ * @internal
360
+ */
299
361
  const identifyKits = new Map();
300
- const identifyHooks = [];
362
+ /**
363
+ * Emitter for identify request events that are not tied to a specific
364
+ * identify instance (login / logout requests).
365
+ *
366
+ * @internal
367
+ */
368
+ const requestsEmitter = new sdkUtil.Emitter();
369
+ /**
370
+ * Read the current locally-owned login policy.
371
+ *
372
+ * Returns `'disabled'` by default.
373
+ *
374
+ * @internal
375
+ */
376
+ function getLoginPolicy() {
377
+ return loginPolicyStore.policy;
378
+ }
379
+ /**
380
+ * Set the login policy.
381
+ *
382
+ * - `'auto'`: the SDK automatically logs the user in whenever
383
+ * credentials are available.
384
+ * - `'disabled'`: credentials are tracked but no automatic login is
385
+ * attempted.
386
+ *
387
+ * Each level of a multi-level integration owns its own policy; the
388
+ * value is never propagated to embedded experiences. Idempotent:
389
+ * setting the same policy is a no-op.
390
+ *
391
+ * @param policy - `'auto'` or `'disabled'`.
392
+ */
393
+ function setLoginPolicy(policy) {
394
+ if (loginPolicyStore.policy === policy) {
395
+ return;
396
+ }
397
+ loginPolicyStore.policy = policy;
398
+ if (policy !== 'auto') {
399
+ return;
400
+ }
401
+ // On transition to 'auto': if credentials are currently set (typical
402
+ // after the non-root module-load pull, or after a setCredentials at
403
+ // the root, or after an upstream Login broadcast has cascaded down),
404
+ // enqueue a login task for each existing identify. If no credentials
405
+ // are set, do nothing — a future credentials arrival via `applyLogin`
406
+ // will trigger the login under this new policy.
407
+ const { credentials } = credentialsStore;
408
+ if (credentials === null) {
409
+ return;
410
+ }
411
+ for (const identify of identifyKits.values()) {
412
+ enqueueLogin(identify, credentials);
413
+ }
414
+ }
415
+ /**
416
+ * Whether the user should be auto-logged in on reconnect.
417
+ *
418
+ * True when the user was previously logged in, the policy is `'auto'`,
419
+ * and credentials are available on the identify instance.
420
+ *
421
+ * @internal
422
+ */
423
+ function shouldLoginOnReconnect(identify) {
424
+ return (identify.wasLoggedIn &&
425
+ getLoginPolicy() === 'auto' &&
426
+ credentialsStore.credentials !== null);
427
+ }
301
428
  /**
302
429
  * @internal
303
430
  */
@@ -334,17 +461,13 @@ async function api(url, token, method = 'GET') {
334
461
  /**
335
462
  * @internal
336
463
  */
337
- async function parentAppRequest(identify, action, payload) {
338
- var _a;
464
+ async function sendParentRequest(action, payload) {
339
465
  const parentApp = sdkLauncherKit.getParentApplication();
340
466
  if (parentApp === null) {
341
467
  throw sdkUtil.createError(exports.IdentifyError.NoParentApplication, IdentifyErrorMessages);
342
468
  }
343
- const { host, projectId } = identify.sdk.options;
344
- // Preserve existing origin (relay) or set from current context (source)
345
- const origin = (_a = payload === null || payload === void 0 ? void 0 : payload.origin) !== null && _a !== void 0 ? _a : { host, projectId };
346
469
  try {
347
- const response = await sdkLauncherKit.sendSdkRequest(parentApp, action, Object.assign(Object.assign({}, payload), { origin }));
470
+ const response = await sdkLauncherKit.sendSdkRequest(parentApp, action, payload);
348
471
  const { error, data } = response.payload;
349
472
  if (error !== undefined) {
350
473
  throw sdkUtil.createError(exports.IdentifyError.ParentAppError, IdentifyErrorMessages, error);
@@ -360,12 +483,6 @@ async function parentAppRequest(identify, action, payload) {
360
483
  throw err;
361
484
  }
362
485
  }
363
- /**
364
- * @internal
365
- */
366
- function registerIdentifyHook(hook) {
367
- identifyHooks.push(hook);
368
- }
369
486
  /**
370
487
  * @internal
371
488
  */
@@ -389,6 +506,9 @@ const logoutWithRetry = sdkUtil.withRetryAsync(logout);
389
506
  * @internal
390
507
  */
391
508
  async function loginTask(identify, credentials) {
509
+ if (identify.state.state === 'logged_in') {
510
+ return;
511
+ }
392
512
  try {
393
513
  identify.state = {
394
514
  state: 'pending',
@@ -402,6 +522,11 @@ async function loginTask(identify, credentials) {
402
522
  }
403
523
  }
404
524
  catch (err) {
525
+ // Abandon any pending login/logout/sync tasks on failure — letting
526
+ // them run after an error would put the user in an inconsistent
527
+ // state. Note: this also drops tasks for unrelated identifies that
528
+ // share the queue; acceptable because the typical runtime has one
529
+ // identify per project.
405
530
  taskQueue.clear();
406
531
  identify.state = {
407
532
  state: 'error',
@@ -414,6 +539,9 @@ async function loginTask(identify, credentials) {
414
539
  * @internal
415
540
  */
416
541
  async function logoutTask(identify) {
542
+ if (identify.state.state === 'logged_out') {
543
+ return;
544
+ }
417
545
  try {
418
546
  identify.state = {
419
547
  state: 'pending',
@@ -427,6 +555,8 @@ async function logoutTask(identify) {
427
555
  }
428
556
  }
429
557
  catch (err) {
558
+ // Abandon any pending login/logout/sync tasks on failure — see
559
+ // `loginTask` for the rationale.
430
560
  taskQueue.clear();
431
561
  identify.state = {
432
562
  state: 'error',
@@ -436,15 +566,55 @@ async function logoutTask(identify) {
436
566
  }
437
567
  }
438
568
  /**
569
+ * Enqueue a `loginTask` for the given identify when `policy === 'auto'`.
570
+ * The downstream `Login` broadcast is emitted by {@link applyLogin}.
571
+ *
439
572
  * @internal
440
573
  */
441
574
  function enqueueLogin(identify, credentials, prioritise = false) {
442
- if (identify.options.loginPolicy === 'auto') {
443
- if (prioritise) {
444
- taskQueue.enqueueFront(() => loginTask(identify, credentials));
445
- }
446
- else {
447
- taskQueue.enqueue(() => loginTask(identify, credentials));
575
+ if (getLoginPolicy() !== 'auto') {
576
+ return;
577
+ }
578
+ if (prioritise) {
579
+ taskQueue.enqueueFront(() => loginTask(identify, credentials));
580
+ }
581
+ else {
582
+ taskQueue.enqueue(() => loginTask(identify, credentials));
583
+ }
584
+ }
585
+ /**
586
+ * Reset the identify's identity-derived caches and enqueue a `logoutTask`
587
+ * when `policy === 'auto'`.
588
+ *
589
+ * @internal
590
+ */
591
+ function enqueueLogout(identify) {
592
+ identify.userData = null;
593
+ identify.signature = null;
594
+ if (getLoginPolicy() !== 'auto') {
595
+ return;
596
+ }
597
+ taskQueue.enqueue(() => logoutTask(identify));
598
+ }
599
+ /**
600
+ * Apply new credentials at this level: update the current credentials,
601
+ * enqueue a `loginTask` for every existing identify on the null-to-set
602
+ * transition, and broadcast `Login` downstream to every embedded
603
+ * experience.
604
+ *
605
+ * Idempotent on token refresh: re-setting when credentials are already
606
+ * present updates the value and broadcasts, but does not re-enqueue
607
+ * logins (their `loginTask` would short-circuit on
608
+ * `state === 'logged_in'` anyway).
609
+ *
610
+ * @internal
611
+ */
612
+ function applyLogin(credentials) {
613
+ const shouldLogin = credentialsStore.credentials === null;
614
+ credentialsStore.credentials = credentials;
615
+ if (shouldLogin) {
616
+ for (const identify of identifyKits.values()) {
617
+ enqueueLogin(identify, credentials);
448
618
  }
449
619
  }
450
620
  for (const experience of getExperiences()) {
@@ -452,14 +622,50 @@ function enqueueLogin(identify, credentials, prioritise = false) {
452
622
  }
453
623
  }
454
624
  /**
625
+ * Clear credentials at this level: clear the current credentials,
626
+ * enqueue a `logoutTask` for every existing identify on the
627
+ * set-to-null transition, and broadcast `Logout` downstream to every
628
+ * embedded experience.
629
+ *
455
630
  * @internal
456
631
  */
457
- function enqueueLogout(identify) {
458
- if (identify.options.loginPolicy === 'auto') {
459
- taskQueue.enqueue(() => logoutTask(identify));
632
+ function applyLogout() {
633
+ const shouldLogout = credentialsStore.credentials !== null;
634
+ credentialsStore.credentials = null;
635
+ if (shouldLogout) {
636
+ for (const identify of identifyKits.values()) {
637
+ enqueueLogout(identify);
638
+ }
460
639
  }
461
640
  for (const experience of getExperiences()) {
462
- sdkLauncherKit.sendSdkMessage(experience, IdentifyAction.Logout);
641
+ sdkLauncherKit.sendSdkMessage(experience, IdentifyAction.Logout, {});
642
+ }
643
+ }
644
+ /**
645
+ * Pull state from the parent application and apply locally.
646
+ *
647
+ * Fires once at non-root bridge module load, regardless of
648
+ * `loginPolicy` — token presence is the customer-side sign-in state and
649
+ * must mirror upstream whether or not we choose to validate against
650
+ * Enmasse. Best-effort: a missing or non-identify-kit parent silently
651
+ * resolves with no change to the current credentials.
652
+ *
653
+ * Uses {@link applyLogin} so the update cascades downstream to this
654
+ * level's own embedded experiences and per-identify loginTasks are
655
+ * enqueued under `loginPolicy === 'auto'`.
656
+ *
657
+ * @internal
658
+ */
659
+ async function pullStateFromParent() {
660
+ let credentials;
661
+ try {
662
+ credentials = await getCredentials();
663
+ }
664
+ catch (_a) {
665
+ return;
666
+ }
667
+ if (credentials !== null) {
668
+ applyLogin(credentials);
463
669
  }
464
670
  }
465
671
  function getIdentify(sdkOrOptions, options) {
@@ -491,94 +697,92 @@ function getIdentify(sdkOrOptions, options) {
491
697
  sdk = sdkCore.getSdk();
492
698
  identifyOptions = {};
493
699
  }
494
- const { options: { projectId }, } = sdk;
700
+ const { projectId } = sdk.options;
495
701
  if (identifyKits.has(projectId)) {
496
702
  return identifyKits.get(projectId);
497
703
  }
498
704
  const identify = new Identify(sdk, identifyOptions);
499
- for (const hook of identifyHooks) {
500
- hook(identify);
501
- }
502
705
  watchConnectionStatus(identify);
503
706
  identifyKits.set(projectId, identify);
504
707
  return identify;
505
708
  }
506
709
  /**
507
- * A function that requests a user login via the `IdentifyKit` of the Monterosa SDK.
710
+ * Request a user login.
711
+ *
712
+ * When called from an embedded experience, the request is relayed to
713
+ * the parent application — the host that owns the auth UI handles it.
508
714
  *
509
715
  * @example
510
716
  * ```javascript
511
717
  * import { configure } from '@monterosa/sdk-core';
512
- * import { getIdentify, requestLogin } from '@monterosa/sdk-identify-kit';
718
+ * import { requestLogin } from '@monterosa/sdk-identify-kit';
513
719
  *
514
720
  * configure({ host: '...', projectId: '...' });
515
721
  *
516
722
  * try {
517
- * const identify = getIdentify();
518
- *
519
- * await requestLogin(identify);
520
- *
723
+ * await requestLogin();
521
724
  * console.log('Login request successful');
522
725
  * } catch (err) {
523
- * console.error('Error requesting login:', error.message)
726
+ * console.error('Error requesting login:', err.message)
524
727
  * }
525
728
  * ```
526
729
  *
527
- * @remarks
528
- * - If the app is running within a third-party application that uses
529
- * the Monterosa SDK, the function delegates to the parent app
530
- * to handle the login process.
531
- *
532
- * @param identify - An instance of the `IdentifyKit` class used for user
533
- * identification.
534
- * @returns A Promise that resolves with `void` when the login request
535
- * is completed.
730
+ * @returns A Promise that resolves once the login request has been
731
+ * delivered.
536
732
  */
537
- async function requestLogin(identify) {
538
- const parentApp = sdkLauncherKit.getParentApplication();
539
- if (parentApp !== null) {
540
- await parentAppRequest(identify, IdentifyAction.RequestLogin);
733
+ async function requestLogin() {
734
+ if (sdkLauncherKit.getParentApplication() !== null) {
735
+ await sendParentRequest(IdentifyAction.RequestLogin);
541
736
  return;
542
737
  }
543
- identify.emit(IdentifyEvent.LoginRequested);
738
+ requestsEmitter.emit(IdentifyEvent.LoginRequested);
544
739
  }
545
740
  /**
546
- * A function that requests a user login via the `IdentifyKit` of the Space.
741
+ * Read the current credentials.
742
+ *
743
+ * When called from an embedded experience, fetches the credentials
744
+ * from the parent application so the caller always sees the
745
+ * authoritative value.
746
+ *
747
+ * @returns A Promise that resolves to the current credentials, or
748
+ * `null` if none are set.
749
+ */
750
+ async function getCredentials() {
751
+ if (sdkLauncherKit.getParentApplication() === null) {
752
+ return credentialsStore.credentials;
753
+ }
754
+ return sendParentRequest(IdentifyAction.GetCredentials);
755
+ }
756
+ /**
757
+ * Request a user logout.
758
+ *
759
+ * When called from an embedded experience, the request is relayed to
760
+ * the parent application — the host that owns the auth UI handles it.
547
761
  *
548
762
  * @example
549
763
  * ```javascript
550
- * import { getSpace } from '@monterosa/sdk-core';
551
- * import { getIdentify, requestLogout } from '@monterosa/sdk-identify-kit';
764
+ * import { configure } from '@monterosa/sdk-core';
765
+ * import { requestLogout } from '@monterosa/sdk-identify-kit';
552
766
  *
553
- * const space = getSpace('host', 'space-id');
554
- * const identify = getIdentify(space);
767
+ * configure({ host: '...', projectId: '...' });
555
768
  *
556
769
  * try {
557
- * await requestLogout(identify);
558
- *
770
+ * await requestLogout();
559
771
  * console.log('Logout request successful');
560
772
  * } catch (err) {
561
- * console.error('Error requesting logout:', error.message)
773
+ * console.error('Error requesting logout:', err.message)
562
774
  * }
563
775
  * ```
564
776
  *
565
- * @remarks
566
- * - If the app is running within a third-party application that uses
567
- * the Space, the function delegates to the parent app
568
- * to handle the logout process.
569
- *
570
- * @param identify - An instance of the `IdentifyKit` class used for user
571
- * identification.
572
- * @returns A Promise that resolves with `void` when the logout request
573
- * is completed.
777
+ * @returns A Promise that resolves once the logout request has been
778
+ * delivered.
574
779
  */
575
- async function requestLogout(identify) {
576
- const parentApp = sdkLauncherKit.getParentApplication();
577
- if (parentApp !== null) {
578
- await parentAppRequest(identify, IdentifyAction.RequestLogout);
780
+ async function requestLogout() {
781
+ if (sdkLauncherKit.getParentApplication() !== null) {
782
+ await sendParentRequest(IdentifyAction.RequestLogout);
579
783
  return;
580
784
  }
581
- identify.emit(IdentifyEvent.LogoutRequested);
785
+ requestsEmitter.emit(IdentifyEvent.LogoutRequested);
582
786
  }
583
787
  /**
584
788
  * @internal
@@ -597,11 +801,6 @@ async function requestLogout(identify) {
597
801
  * @returns A Promise that resolves to a `Signature` object.
598
802
  */
599
803
  async function getSessionSignature(identify, credentials) {
600
- const parentApp = sdkLauncherKit.getParentApplication();
601
- if (parentApp !== null) {
602
- const signature = await parentAppRequest(identify, IdentifyAction.GetSessionSignature, credentials);
603
- return signature;
604
- }
605
804
  if (identify.signature !== null) {
606
805
  return identify.signature;
607
806
  }
@@ -612,148 +811,118 @@ async function getSessionSignature(identify, credentials) {
612
811
  return signature;
613
812
  }
614
813
  /**
615
- * A memoized version of the `getSessionSignature` function.
814
+ * @internal
815
+ *
816
+ * A memoized version of the `getSessionSignature` function. Memo key is
817
+ * the credentials token, so both leaf-side and bridge-side callers share
818
+ * the same cache for the same token.
616
819
  */
617
820
  const getSessionSignatureMemoized = sdkUtil.memoizePromise(getSessionSignature, (identify, credentials) => credentials.token, {
618
821
  clearOnResolve: true,
619
822
  clearOnReject: true,
620
823
  });
621
824
  /**
622
- * The function that takes an instance of `IdentifyKit` as its argument and
623
- * returns a Promise that resolves to a key-value object representing user data.
825
+ * Fetch user data for the given credentials.
826
+ *
827
+ * Credentials are required explicitly. Obtain a value via
828
+ * {@link getCredentials} or the {@link onCredentialsUpdated} callback.
624
829
  *
625
830
  * @example
626
831
  * ```javascript
627
832
  * import { configure } from '@monterosa/sdk-core';
628
- * import { getIdentify, getUserData } from '@monterosa/sdk-identify-kit';
833
+ * import {
834
+ * getIdentify,
835
+ * getUserData,
836
+ * getCredentials,
837
+ * } from '@monterosa/sdk-identify-kit';
629
838
  *
630
839
  * configure({ host: '...', projectId: '...' });
631
840
  *
632
841
  * const identify = getIdentify();
633
- * const userData = await getUserData(identify);
842
+ * const credentials = await getCredentials();
634
843
  *
635
- * console.log('User data:', userData);
844
+ * if (credentials !== null) {
845
+ * const userData = await getUserData(identify, credentials);
846
+ * console.log('User data:', userData);
847
+ * }
636
848
  * ```
637
849
  *
638
850
  * @remarks
639
- * - If the app is running within a third-party application that uses
640
- * the Monterosa SDK, the function delegates to the parent app
641
- * to get user data.
642
- *
643
- * - If the request is successful, the function resolves with a key-value object
644
- * representing user data. If not, a `MonterosaError` is thrown.
645
- *
646
- * @param identify - An instance of `IdentifyKit` that provides the user
647
- * identification functionality.
648
- * @returns A Promise that resolves to a key-value object representing user data.
649
- * The structure and content of the user data object depend on the identify
650
- * service provider and may vary. It typically contains information about the user,
651
- * but the specific fields are determined by the Identify service provider.
851
+ * Cached after the first successful fetch and reset when credentials
852
+ * are cleared.
853
+ *
854
+ * @param identify - The IdentifyKit instance.
855
+ * @param credentials - The user's authentication credentials.
856
+ * @returns A Promise that resolves to a key-value object of user data.
857
+ * The structure depends on the identify service provider.
652
858
  */
653
- async function getUserData(identify) {
654
- const parentApp = sdkLauncherKit.getParentApplication();
655
- if (parentApp !== null) {
656
- const userData = await parentAppRequest(identify, IdentifyAction.GetUserData);
657
- return userData;
658
- }
659
- // Return cached user data if available
859
+ async function getUserData(identify, credentials) {
660
860
  if (identify.userData !== null) {
661
861
  return identify.userData;
662
862
  }
663
- if (identify.credentials === null) {
664
- throw sdkUtil.createError(exports.IdentifyError.NoCredentials, IdentifyErrorMessages);
665
- }
666
863
  const url = await identify.getUrl('/user');
667
- const { data } = await api(url, identify.credentials.token);
864
+ const { data } = await api(url, credentials.token);
668
865
  identify.userData = data;
669
866
  return data;
670
867
  }
671
868
  /**
672
- * Sets the user's authentication credentials.
869
+ * Set the user's authentication credentials.
870
+ *
871
+ * The credentials become the active credentials for the entire
872
+ * integration. When called from an embedded experience, the call is
873
+ * relayed to the parent application so that every level of the
874
+ * integration sees the new value.
673
875
  *
674
876
  * @example
675
877
  * ```javascript
676
878
  * import { configure } from '@monterosa/sdk-core';
677
- * import { getIdentify, setCredentials } from '@monterosa/sdk-identify-kit';
879
+ * import { setCredentials } from '@monterosa/sdk-identify-kit';
678
880
  *
679
881
  * configure({ host: '...', projectId: '...' });
680
882
  *
681
- * const credentials = { token: 'abc123' };
682
- * const identify = getIdentify();
683
- *
684
- * await setCredentials(identify, credentials)
883
+ * await setCredentials({ token: 'abc123' });
685
884
  * ```
686
885
  *
687
- * @remarks
688
- * - If the app is running within a third-party application that uses
689
- * the Monterosa SDK, the function delegates to the parent app
690
- * to set user credentials.
691
- *
692
- * - If the request is successful, the function resolves to `void`.
693
- * If not, a `MonterosaError` is thrown.
694
- *
695
- * @param identify - An instance of `IdentifyKit` that provides the user
696
- * identification functionality.
697
- * @param credentials - An object representing the user's authentication
698
- * credentials.
699
- * @returns A Promise that resolves to `void`.
886
+ * @param credentials - The user's authentication credentials.
887
+ * @returns A Promise that resolves once the credentials have been
888
+ * applied.
700
889
  */
701
- async function setCredentials(identify, credentials) {
702
- const parentApp = sdkLauncherKit.getParentApplication();
703
- if (parentApp !== null) {
704
- await parentAppRequest(identify, IdentifyAction.SetCredentials, credentials);
890
+ async function setCredentials(credentials) {
891
+ if (sdkLauncherKit.getParentApplication() !== null) {
892
+ await sendParentRequest(IdentifyAction.SetCredentials, credentials);
705
893
  return;
706
894
  }
707
- const shouldLogin = identify.credentials === null;
708
- identify.credentials = credentials;
709
- if (shouldLogin) {
710
- enqueueLogin(identify, credentials);
711
- }
895
+ applyLogin(credentials);
712
896
  }
713
897
  /**
714
- * Clears the user's authentication credentials.
898
+ * Clear the user's authentication credentials.
899
+ *
900
+ * When called from an embedded experience, the call is relayed to the
901
+ * parent application so that every level of the integration is
902
+ * cleared.
715
903
  *
716
904
  * @example
717
905
  * ```javascript
718
906
  * import { configure } from '@monterosa/sdk-core';
719
- * import { getIdentify, clearCredentials } from '@monterosa/sdk-identify-kit';
907
+ * import { clearCredentials } from '@monterosa/sdk-identify-kit';
720
908
  *
721
909
  * configure({ host: '...', projectId: '...' });
722
910
  *
723
- * const identify = getIdentify();
724
- *
725
- * await clearCredentials(identify);
911
+ * await clearCredentials();
726
912
  * ```
727
913
  *
728
- * @remarks
729
- * - If the app is running within a third-party application that uses
730
- * the Monterosa SDK, the function delegates to the parent app
731
- * to clear user credentials.
732
- *
733
- * - If the request is successful, the function resolves to `void`.
734
- * If not, a `MonterosaError` is thrown.
735
- *
736
- * @param identify - An instance of `IdentifyKit` that provides the user
737
- * identification functionality.
738
- * @returns A Promise that resolves to `void`.
914
+ * @returns A Promise that resolves once the credentials have been
915
+ * cleared.
739
916
  */
740
- async function clearCredentials(identify) {
741
- const parentApp = sdkLauncherKit.getParentApplication();
742
- if (parentApp !== null) {
743
- await parentAppRequest(identify, IdentifyAction.ClearCredentials);
917
+ async function clearCredentials() {
918
+ if (sdkLauncherKit.getParentApplication() !== null) {
919
+ await sendParentRequest(IdentifyAction.ClearCredentials);
744
920
  return;
745
921
  }
746
- const shouldLogout = identify.credentials !== null;
747
- identify.credentials = null;
748
- identify.userData = null;
749
- identify.signature = null;
750
- if (shouldLogout) {
751
- enqueueLogout(identify);
752
- }
922
+ applyLogout();
753
923
  }
754
924
  /**
755
- * Registers a callback function that will be called whenever the `LoginState`
756
- * object associated with the `IdentifyKit` instance is updated.
925
+ * Register a callback for `LoginState` updates on the given identify.
757
926
  *
758
927
  * @example
759
928
  * ```javascript
@@ -767,203 +936,97 @@ async function clearCredentials(identify) {
767
936
  * const unsubscribe = onStateUpdated(identify, (state) => {
768
937
  * console.log("State updated:", state);
769
938
  * });
770
- *
771
- * // Call unsubscribe() to unregister the callback function
772
- * // unsubscribe();
773
939
  * ```
774
940
  *
775
- * @param identify - An instance of `IdentifyKit` that provides the user
776
- * identification functionality.
777
- * @param callback - The callback function to register. This function will be
778
- * called with the updated `LoginState` object as its only argument.
779
- * @returns An `Unsubscribe` function that can be called to unregister
780
- * the callback function.
941
+ * @param identify - The IdentifyKit instance.
942
+ * @param callback - Called with the updated `LoginState`.
943
+ * @returns An `Unsubscribe` function.
781
944
  */
782
945
  function onStateUpdated(identify, callback) {
783
946
  return sdkUtil.subscribe(identify, IdentifyEvent.StateUpdated, callback);
784
947
  }
785
948
  /**
786
- * Registers a callback function that will be called whenever the `Credentials`
787
- * object associated with the `IdentifyKit` instance is updated.
949
+ * Register a callback for updates to the current credentials.
788
950
  *
789
951
  * @example
790
952
  * ```javascript
791
953
  * import { configure } from '@monterosa/sdk-core';
792
- * import { getIdentify, onCredentialsUpdated } from '@monterosa/sdk-identify-kit';
954
+ * import { onCredentialsUpdated } from '@monterosa/sdk-identify-kit';
793
955
  *
794
956
  * configure({ host: '...', projectId: '...' });
795
957
  *
796
- * const identify = getIdentify();
797
- *
798
- * const unsubscribe = onCredentialsUpdated(identify, (credentials) => {
958
+ * const unsubscribe = onCredentialsUpdated((credentials) => {
799
959
  * if (credentials !== null) {
800
960
  * console.log("Credentials updated:", credentials);
801
961
  * } else {
802
962
  * console.log("Credentials cleared.");
803
963
  * }
804
964
  * });
805
- *
806
- * // Call unsubscribe() to unregister the callback function
807
- * // unsubscribe();
808
965
  * ```
809
966
  *
810
- * @param identify - An instance of `IdentifyKit` that provides the user
811
- * identification functionality.
812
- * @param callback - The callback function to register. This function will be
813
- * called with the updated `Credentials` object as its only argument.
814
- * If the value `null` is received, it indicates that the signature has
815
- * been cleared
816
- * @returns An `Unsubscribe` function that can be called to unregister
817
- * the callback function.
967
+ * @param callback - Called with the updated `Credentials`, or `null`
968
+ * when credentials are cleared.
969
+ * @returns An `Unsubscribe` function.
818
970
  */
819
- function onCredentialsUpdated(identify, callback) {
820
- return sdkUtil.subscribe(identify, IdentifyEvent.CredentialsUpdated, callback);
971
+ function onCredentialsUpdated(callback) {
972
+ return credentialsStore.subscribe(callback);
821
973
  }
822
974
  /**
823
- * Registers a callback function that will be called whenever the `Signature`
824
- * object associated with the `IdentifyKit` instance is updated.
975
+ * Register a callback for login requests.
825
976
  *
826
- * @example
827
- * ```javascript
828
- * import { configure } from '@monterosa/sdk-core';
829
- * import { getIdentify, onSignatureUpdated } from '@monterosa/sdk-identify-kit';
830
- *
831
- * configure({ host: '...', projectId: '...' });
832
- *
833
- * const identify = getIdentify();
834
- *
835
- * const unsubscribe = onSignatureUpdated(identify, (signature) => {
836
- * if (signature !== null) {
837
- * console.log("Signature updated:", signature);
838
- * } else {
839
- * console.log("Signature cleared.");
840
- * }
841
- * });
842
- *
843
- * // Call unsubscribe() to unregister the callback function
844
- * // unsubscribe();
845
- * ```
846
- *
847
- * @param identify - An instance of `IdentifyKit` that provides the user
848
- * identification functionality.
849
- * @param callback - The callback function to register. This function will be
850
- * called with the updated `Signature` object as its only argument.
851
- * If the value `null` is received, it indicates that the signature has
852
- * been cleared
853
- * @returns An `Unsubscribe` function that can be called to unregister
854
- * the callback function.
855
- */
856
- function onSignatureUpdated(identify, callback) {
857
- return sdkUtil.subscribe(identify, IdentifyEvent.SignatureUpdated, callback);
858
- }
859
- /**
860
- * Registers a callback function that will be called whenever the `UserData`
861
- * object associated with the `IdentifyKit` instance is updated.
977
+ * Fires when {@link requestLogin} is called at this level — whether by
978
+ * local code or relayed up from an embedded experience.
862
979
  *
863
980
  * @example
864
981
  * ```javascript
865
982
  * import { configure } from '@monterosa/sdk-core';
866
- * import { getIdentify, onUserDataUpdated } from '@monterosa/sdk-identify-kit';
983
+ * import { onLoginRequestedByExperience } from '@monterosa/sdk-identify-kit';
867
984
  *
868
985
  * configure({ host: '...', projectId: '...' });
869
986
  *
870
- * const identify = getIdentify();
871
- *
872
- * const unsubscribe = onUserDataUpdated(identify, (userData) => {
873
- * if (userData !== null) {
874
- * console.log("User's data updated:", userData);
875
- * } else {
876
- * console.log("User's data cleared.");
877
- * }
987
+ * const unsubscribe = onLoginRequestedByExperience(() => {
988
+ * showLoginForm();
878
989
  * });
879
- *
880
- * // Call unsubscribe() to unregister the callback function
881
- * // unsubscribe();
882
990
  * ```
883
991
  *
884
- * @param identify - An instance of `IdentifyKit` that provides the user
885
- * identification functionality.
886
- * @param callback - The callback function to register. This function will be
887
- * called with the updated `UserData` object as its only argument.
888
- * If the value `null` is received, it indicates that the user's data has
889
- * been cleared
890
- * @returns An `Unsubscribe` function that can be called to unregister
891
- * the callback function.
992
+ * @param callback - Called when a login is requested.
993
+ * @returns An `Unsubscribe` function.
892
994
  */
893
- function onUserDataUpdated(identify, callback) {
894
- return sdkUtil.subscribe(identify, IdentifyEvent.UserdataUpdated, callback);
995
+ function onLoginRequestedByExperience(callback) {
996
+ return sdkUtil.subscribe(requestsEmitter, IdentifyEvent.LoginRequested, callback);
895
997
  }
896
998
  /**
897
- * Registers a callback function that will be called when a login is requested
898
- * by an Experience.
999
+ * Register a callback for logout requests.
1000
+ *
1001
+ * Fires when {@link requestLogout} is called at this level — whether
1002
+ * by local code or relayed up from an embedded experience.
899
1003
  *
900
1004
  * @example
901
1005
  * ```javascript
902
1006
  * import { configure } from '@monterosa/sdk-core';
903
- * import { getIdentify, onLoginRequestedByExperience } from '@monterosa/sdk-identify-kit';
1007
+ * import { onLogoutRequestedByExperience } from '@monterosa/sdk-identify-kit';
904
1008
  *
905
1009
  * configure({ host: '...', projectId: '...' });
906
1010
  *
907
- * const identify = getIdentify();
908
- *
909
- * const unsubscribe = onLoginRequestedByExperience(identify, () => {
910
- * showLoginForm();
911
- * });
912
- *
913
- * // Call unsubscribe() to unregister the callback function
914
- * // unsubscribe();
915
- * ```
916
- *
917
- * @param identify - An instance of `IdentifyKit` that provides the user
918
- * identification functionality.
919
- * @param callback - The callback function to register. This function will
920
- * be called when a login is requested by an Experience.
921
- * @returns An `Unsubscribe` function that can be called to unregister
922
- * the callback function.
923
- */
924
- function onLoginRequestedByExperience(identify, callback) {
925
- return sdkUtil.subscribe(identify, IdentifyEvent.LoginRequested, callback);
926
- }
927
- /**
928
- * Registers a callback function that will be called when a logout is requested
929
- * by an Experience.
930
- *
931
- * @example
932
- * ```javascript
933
- * import { getSpace } from '@monterosa/sdk-core';
934
- * import { getIdentify, onLogoutRequestedByExperience } from '@monterosa/sdk-identify-kit';
935
- *
936
- * const space = getSpace('host', 'space-id');
937
- * const identify = getIdentify(space);
938
- *
939
- * const unsubscribe = onLogoutRequestedByExperience(identify, () => {
940
- * // logout requested by experience
941
- * // perform logout from Auth service
1011
+ * const unsubscribe = onLogoutRequestedByExperience(() => {
1012
+ * // perform logout from auth service
942
1013
  * });
943
- *
944
- * // Call unsubscribe() to unregister the callback function
945
- * // unsubscribe();
946
1014
  * ```
947
1015
  *
948
- * @param identify - An instance of `IdentifyKit` that provides the user
949
- * identification functionality.
950
- * @param callback - The callback function to register. This function will
951
- * be called when a logout is requested by an Experience.
952
- * @returns An `Unsubscribe` function that can be called to unregister
953
- * the callback function.
1016
+ * @param callback - Called when a logout is requested.
1017
+ * @returns An `Unsubscribe` function.
954
1018
  */
955
- function onLogoutRequestedByExperience(identify, callback) {
956
- return sdkUtil.subscribe(identify, IdentifyEvent.LogoutRequested, callback);
1019
+ function onLogoutRequestedByExperience(callback) {
1020
+ return sdkUtil.subscribe(requestsEmitter, IdentifyEvent.LogoutRequested, callback);
957
1021
  }
958
1022
  /**
959
- *
960
1023
  * @internal
961
1024
  */
962
1025
  async function watchConnectionStatus(identify) {
963
1026
  const conn = await sdkConnectKit.getConnect(identify.sdk.options.host);
964
1027
  sdkConnectKit.onConnected(conn, () => {
965
- if (identify.shouldLoginOnReconnect) {
966
- enqueueLogin(identify, identify.credentials, true);
1028
+ if (shouldLoginOnReconnect(identify)) {
1029
+ enqueueLogin(identify, credentialsStore.credentials, true);
967
1030
  }
968
1031
  taskQueue.resume();
969
1032
  });
@@ -1000,115 +1063,59 @@ async function watchConnectionStatus(identify) {
1000
1063
  * More details on the license can be found at https://www.monterosa.co/sdk/license
1001
1064
  */
1002
1065
  /**
1066
+ * Process an incoming `Login` / `Logout` broadcast from the parent
1067
+ * application. Updates the local current credentials, enqueues login/logout
1068
+ * for every existing identify, and forwards the broadcast downstream to
1069
+ * this level's own embedded experiences — the mechanism that cascades a
1070
+ * root-level `setCredentials` through every nested experience.
1071
+ *
1003
1072
  * @internal
1004
1073
  */
1005
- function parentMessagesHook(identify) {
1006
- const parentApp = sdkLauncherKit.getParentApplication();
1007
- if (parentApp === null) {
1008
- return () => { };
1009
- }
1010
- return sdkLauncherKit.onSdkMessage(parentApp, async (message) => {
1011
- switch (message.action) {
1012
- case IdentifyAction.OnCredentialsUpdated: {
1013
- identify.credentials = message.payload.data;
1014
- break;
1015
- }
1016
- case IdentifyAction.OnSessionSignatureUpdated: {
1017
- identify.signature = message.payload.data;
1018
- break;
1019
- }
1020
- case IdentifyAction.OnUserDataUpdated: {
1021
- identify.userData = message.payload.data;
1022
- break;
1023
- }
1024
- case IdentifyAction.Login: {
1025
- enqueueLogin(identify, message.payload);
1026
- break;
1027
- }
1028
- case IdentifyAction.Logout: {
1029
- enqueueLogout(identify);
1030
- break;
1031
- }
1074
+ function handleParentMessage(message) {
1075
+ switch (message.action) {
1076
+ case IdentifyAction.Login: {
1077
+ applyLogin(message.payload);
1078
+ break;
1032
1079
  }
1033
- });
1034
- }
1035
- /**
1036
- * Finds an existing SDK with matching projectId, or creates a new one.
1037
- */
1038
- function getOrConfigureSdk(host, projectId) {
1039
- const existingSdk = sdkCore.getSdks().find((sdk) => sdk.options.projectId === projectId);
1040
- return existingSdk !== null && existingSdk !== void 0 ? existingSdk : sdkCore.configure({ host, projectId }, projectId);
1080
+ case IdentifyAction.Logout: {
1081
+ applyLogout();
1082
+ break;
1083
+ }
1084
+ }
1041
1085
  }
1042
1086
  /**
1043
1087
  * @internal
1044
1088
  */
1045
1089
  function handleExperienceEmbedded(experience) {
1046
- const identify = getIdentify(experience.sdk);
1047
- // Send login action with current credentials to the new experience if available.
1048
- // The bridge queues this message until the experience is initialised.
1049
- if (identify.credentials) {
1050
- sdkLauncherKit.sendSdkMessage(experience, IdentifyAction.Login, identify.credentials);
1051
- }
1052
- const credentialsUpdatedUnsub = onCredentialsUpdated(identify, (data) => {
1053
- sdkLauncherKit.sendSdkMessage(experience, IdentifyAction.OnCredentialsUpdated, {
1054
- data,
1055
- });
1056
- });
1057
- const signatureUpdatedUnsub = onSignatureUpdated(identify, (data) => {
1058
- sdkLauncherKit.sendSdkMessage(experience, IdentifyAction.OnSessionSignatureUpdated, {
1059
- data,
1060
- });
1061
- });
1062
- const userDataUpdatedUnsub = onUserDataUpdated(identify, (data) => {
1063
- sdkLauncherKit.sendSdkMessage(experience, IdentifyAction.OnUserDataUpdated, {
1064
- data,
1065
- });
1066
- });
1067
1090
  const sdkMessageUnsub = sdkLauncherKit.onSdkMessage(experience, async (message) => {
1068
1091
  if (!Object.values(IdentifyAction).includes(message.action)) {
1069
1092
  return;
1070
1093
  }
1071
- // Extract origin context from payload if available.
1072
- // New clients include origin (host, projectId) to ensure correct project context
1073
- // in multilevel integrations. Old clients don't send origin, so we fall back
1074
- // to the experience's SDK to maintain backward compatibility.
1075
- const { origin } = message.payload;
1076
- const originSdk = origin
1077
- ? getOrConfigureSdk(origin.host, origin.projectId)
1078
- : experience.sdk;
1079
- const originIdentify = getIdentify(originSdk);
1080
1094
  const respond = (payload) => sdkLauncherKit.respondToSdkMessage(experience, message, payload);
1081
1095
  try {
1082
1096
  switch (message.action) {
1083
1097
  case IdentifyAction.RequestLogin: {
1084
- await requestLogin(originIdentify);
1098
+ await requestLogin();
1085
1099
  respond();
1086
1100
  break;
1087
1101
  }
1088
1102
  case IdentifyAction.RequestLogout: {
1089
- await requestLogout(identify);
1103
+ await requestLogout();
1090
1104
  respond();
1091
1105
  break;
1092
1106
  }
1093
- case IdentifyAction.GetUserData: {
1094
- const data = await getUserData(identify);
1107
+ case IdentifyAction.GetCredentials: {
1108
+ const data = await getCredentials();
1095
1109
  respond({ data });
1096
1110
  break;
1097
1111
  }
1098
- case IdentifyAction.GetSessionSignature: {
1099
- const signature = await getSessionSignatureMemoized(identify, message.payload);
1100
- respond({ data: signature });
1101
- break;
1102
- }
1103
1112
  case IdentifyAction.SetCredentials: {
1104
- await setCredentials(originIdentify, {
1105
- token: message.payload.token,
1106
- });
1113
+ await setCredentials(message.payload);
1107
1114
  respond();
1108
1115
  break;
1109
1116
  }
1110
1117
  case IdentifyAction.ClearCredentials: {
1111
- await clearCredentials(identify);
1118
+ await clearCredentials();
1112
1119
  respond();
1113
1120
  break;
1114
1121
  }
@@ -1120,12 +1127,7 @@ function handleExperienceEmbedded(experience) {
1120
1127
  });
1121
1128
  }
1122
1129
  });
1123
- addExperience(experience, [
1124
- credentialsUpdatedUnsub,
1125
- signatureUpdatedUnsub,
1126
- userDataUpdatedUnsub,
1127
- sdkMessageUnsub,
1128
- ]);
1130
+ addExperience(experience, [sdkMessageUnsub]);
1129
1131
  }
1130
1132
  /**
1131
1133
  * @internal
@@ -1133,26 +1135,42 @@ function handleExperienceEmbedded(experience) {
1133
1135
  function handleExperienceUnmounted(experience) {
1134
1136
  deleteExperience(experience);
1135
1137
  }
1136
- sdkLauncherKit.onStateChanged((experience, state) => {
1138
+ /**
1139
+ * @internal
1140
+ */
1141
+ function handleExperienceStateChange(experience, state) {
1137
1142
  if (state === 'mounted') {
1138
1143
  handleExperienceEmbedded(experience);
1144
+ return;
1139
1145
  }
1140
- else if (state === 'unmounted') {
1146
+ if (state === 'unmounted') {
1141
1147
  handleExperienceUnmounted(experience);
1142
1148
  }
1143
- });
1144
- registerIdentifyHook(parentMessagesHook);
1149
+ }
1150
+ function subscribeToExperienceLifecycle() {
1151
+ sdkLauncherKit.onStateChanged(handleExperienceStateChange);
1152
+ }
1153
+ function connectToParentApplication() {
1154
+ const parentApp = sdkLauncherKit.getParentApplication();
1155
+ if (parentApp === null) {
1156
+ return;
1157
+ }
1158
+ sdkLauncherKit.onSdkMessage(parentApp, handleParentMessage);
1159
+ pullStateFromParent();
1160
+ }
1161
+ subscribeToExperienceLifecycle();
1162
+ connectToParentApplication();
1145
1163
 
1146
1164
  exports.clearCredentials = clearCredentials;
1165
+ exports.getCredentials = getCredentials;
1147
1166
  exports.getIdentify = getIdentify;
1148
1167
  exports.getUserData = getUserData;
1149
1168
  exports.onCredentialsUpdated = onCredentialsUpdated;
1150
1169
  exports.onLoginRequestedByExperience = onLoginRequestedByExperience;
1151
1170
  exports.onLogoutRequestedByExperience = onLogoutRequestedByExperience;
1152
- exports.onSignatureUpdated = onSignatureUpdated;
1153
1171
  exports.onStateUpdated = onStateUpdated;
1154
- exports.onUserDataUpdated = onUserDataUpdated;
1155
1172
  exports.requestLogin = requestLogin;
1156
1173
  exports.requestLogout = requestLogout;
1157
1174
  exports.setCredentials = setCredentials;
1175
+ exports.setLoginPolicy = setLoginPolicy;
1158
1176
  //# sourceMappingURL=index.cjs.map