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