@thor-commerce/app-bridge-react 0.7.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,6 +7,7 @@ var EMBEDDED_LAUNCH_PARAMS = [
7
7
  "id_token",
8
8
  "link_source",
9
9
  "locale",
10
+ "project",
10
11
  "protocol",
11
12
  "session",
12
13
  "shop",
@@ -72,6 +73,37 @@ function sanitizeEmbeddedAppPath(path) {
72
73
  }
73
74
  return `${url.pathname}${url.search}${url.hash}`;
74
75
  }
76
+ function preserveEmbeddedAppLaunchParams(path, currentHref) {
77
+ if (!path || !currentHref) {
78
+ return path;
79
+ }
80
+ try {
81
+ const currentUrl = new URL(currentHref, NAVIGATION_BASE_URL);
82
+ const nextUrl = new URL(path, currentUrl.href);
83
+ if (nextUrl.origin !== currentUrl.origin) {
84
+ return path;
85
+ }
86
+ let changed = false;
87
+ for (const key of EMBEDDED_LAUNCH_PARAMS) {
88
+ if (!nextUrl.searchParams.has(key) && currentUrl.searchParams.has(key)) {
89
+ const value = currentUrl.searchParams.get(key);
90
+ if (value != null) {
91
+ nextUrl.searchParams.set(key, value);
92
+ changed = true;
93
+ }
94
+ }
95
+ }
96
+ if (!changed) {
97
+ return path;
98
+ }
99
+ if (/^https?:\/\//i.test(path)) {
100
+ return nextUrl.toString();
101
+ }
102
+ return `${nextUrl.pathname}${nextUrl.search}${nextUrl.hash}`;
103
+ } catch {
104
+ return path;
105
+ }
106
+ }
75
107
  function resolveLocalNavigationPath(href, currentOrigin) {
76
108
  if (!href || href.startsWith("#")) {
77
109
  return null;
@@ -146,13 +178,6 @@ function normalizeBridgeNavigationItems(items) {
146
178
  }
147
179
 
148
180
  // src/core.ts
149
- var PRESERVED_EMBEDDED_DOCUMENT_PARAMS = [
150
- "hmac",
151
- "id_token",
152
- "project",
153
- "tenant",
154
- "timestamp"
155
- ];
156
181
  var DEFAULT_NAMESPACE = "thorcommerce:app-bridge";
157
182
  var DEFAULT_TIMEOUT_MS = 1e4;
158
183
  var DEFAULT_REDIRECT_EVENT_TYPE = "navigation:redirect";
@@ -466,273 +491,162 @@ var AppBridge = class {
466
491
  throw new Error("AppBridge could not resolve a browser window for redirect.");
467
492
  }
468
493
  this.selfWindow.location.assign(
469
- preserveEmbeddedDocumentParams(destination, this.selfWindow.location.href)
494
+ preserveEmbeddedAppLaunchParams(destination, this.selfWindow.location.href) ?? destination
470
495
  );
471
496
  }
472
497
  };
473
- function preserveEmbeddedDocumentParams(destination, currentHref) {
474
- try {
475
- const currentUrl = new URL(currentHref);
476
- const nextUrl = new URL(destination, currentUrl.href);
477
- if (nextUrl.origin !== currentUrl.origin) {
478
- return destination;
479
- }
480
- let changed = false;
481
- for (const key of PRESERVED_EMBEDDED_DOCUMENT_PARAMS) {
482
- if (!nextUrl.searchParams.has(key) && currentUrl.searchParams.has(key)) {
483
- const value = currentUrl.searchParams.get(key);
484
- if (value != null) {
485
- nextUrl.searchParams.set(key, value);
486
- changed = true;
487
- }
488
- }
489
- }
490
- return changed ? nextUrl.toString() : destination;
491
- } catch {
492
- return destination;
493
- }
494
- }
495
498
  function createAppBridge(options = {}) {
496
499
  return new AppBridge(options);
497
500
  }
498
501
 
499
- // src/react.tsx
500
- import {
501
- createContext,
502
- useContext,
503
- useEffect,
504
- useMemo,
505
- useRef,
506
- useState
507
- } from "react";
508
- import { jsx } from "react/jsx-runtime";
509
- var AppBridgeContext = createContext(null);
510
- function AppBridgeProvider({
511
- children,
512
- clientId,
513
- currentPath,
514
- navigationItems,
515
- navigationEventType = "navigation:go",
516
- navigationUpdateEventType = "navigation:update",
517
- namespace,
518
- onNavigate,
519
- readyEventType = "app:ready",
520
- readyPayload,
521
- requestTimeoutMs,
522
- selfWindow,
523
- targetOrigin,
524
- targetWindow
525
- }) {
526
- const [bridge, setBridge] = useState(null);
527
- const onNavigateRef = useRef(onNavigate);
528
- const normalizedNavigationItems = useMemo(
529
- () => normalizeBridgeNavigationItems(navigationItems),
530
- [navigationItems]
531
- );
532
- const sessionTokenCacheRef = useRef(null);
533
- const projectRef = useRef(readInitialProject(selfWindow));
534
- const pendingSessionTokenRef = useRef(null);
535
- useEffect(() => {
536
- onNavigateRef.current = onNavigate;
537
- }, [onNavigate]);
538
- useEffect(() => {
539
- if (typeof window === "undefined" && !selfWindow) {
540
- return;
541
- }
542
- const resolvedTargetOrigin = targetOrigin ?? getReferrerOrigin(selfWindow);
543
- const resolvedAllowedOrigins = resolvedTargetOrigin ? [resolvedTargetOrigin] : void 0;
544
- const nextBridge = createAppBridge({
545
- allowedOrigins: resolvedAllowedOrigins,
546
- clientId,
547
- namespace,
548
- requestTimeoutMs,
549
- selfWindow,
502
+ // src/runtime.ts
503
+ var GLOBAL_RUNTIME_KEY = "__thorEmbeddedAppRuntime__";
504
+ var THOR_NAVIGATE_EVENT = "thor:navigate";
505
+ var EmbeddedAppRuntime = class {
506
+ constructor(config) {
507
+ this.currentPath = null;
508
+ this.navigationItems = [];
509
+ this.navigationEventType = "navigation:go";
510
+ this.navigationUpdateEventType = "navigation:update";
511
+ this.readyEventType = "app:ready";
512
+ this.sessionTokenCache = null;
513
+ this.pendingSessionToken = null;
514
+ const resolvedWindow = config.selfWindow ?? (typeof window !== "undefined" ? window : void 0);
515
+ if (!resolvedWindow) {
516
+ throw new Error("EmbeddedAppRuntime requires a browser window.");
517
+ }
518
+ this.selfWindow = resolvedWindow;
519
+ this.targetOrigin = config.targetOrigin ?? getReferrerOrigin(resolvedWindow);
520
+ this.clientId = config.clientId;
521
+ this.project = readInitialProject(resolvedWindow);
522
+ this.readyPayload = config.readyPayload ?? { clientId: config.clientId };
523
+ this.bridge = createAppBridge({
524
+ allowedOrigins: this.targetOrigin ? [this.targetOrigin] : void 0,
525
+ namespace: config.namespace,
526
+ requestTimeoutMs: config.requestTimeoutMs,
527
+ selfWindow: resolvedWindow,
550
528
  source: "embedded-app",
551
529
  target: "dashboard",
552
- targetOrigin: resolvedTargetOrigin,
553
- targetWindow
554
- });
555
- setBridge(nextBridge);
556
- return () => {
557
- setBridge((currentBridge) => currentBridge === nextBridge ? null : currentBridge);
558
- nextBridge.destroy();
559
- };
560
- }, [
561
- clientId,
562
- namespace,
563
- requestTimeoutMs,
564
- selfWindow,
565
- targetOrigin,
566
- targetWindow
567
- ]);
568
- useEffect(() => {
569
- if (!bridge || !bridge.hasTargetWindow()) {
570
- return;
571
- }
572
- bridge.send(
573
- readyEventType,
574
- readyPayload ?? {
575
- clientId
576
- }
577
- );
578
- }, [bridge, clientId, readyEventType, readyPayload]);
579
- useEffect(() => {
580
- if (!bridge || !bridge.hasTargetWindow()) {
581
- return;
582
- }
583
- bridge.send("navigation:items:update", {
584
- items: normalizedNavigationItems
530
+ targetOrigin: this.targetOrigin,
531
+ targetWindow: config.targetWindow
585
532
  });
586
- }, [bridge, normalizedNavigationItems]);
587
- useEffect(() => {
588
- if (!bridge || !bridge.hasTargetWindow() || !currentPath) {
589
- return;
590
- }
591
- bridge.send(navigationUpdateEventType, buildNavigationUpdatePayload(currentPath));
592
- }, [bridge, currentPath, navigationUpdateEventType]);
593
- useEffect(() => {
594
- if (!bridge || !onNavigate) {
595
- return;
596
- }
597
- return bridge.on(navigationEventType, (message) => {
533
+ this.removeNavigationRequestHandler = this.bridge.on(this.navigationEventType, (message) => {
598
534
  const destination = resolveNavigationDestination(message.payload);
599
535
  if (!destination) {
600
536
  return;
601
537
  }
602
- onNavigateRef.current?.(destination, message);
538
+ const nextPath = preserveEmbeddedAppLaunchParams(
539
+ destination,
540
+ this.selfWindow.location.href
541
+ );
542
+ this.navigate(nextPath ?? destination, message);
603
543
  });
604
- }, [bridge, navigationEventType, onNavigate]);
605
- useEffect(() => {
606
- if (!bridge || !onNavigate || typeof document === "undefined" || typeof window === "undefined") {
607
- return;
608
- }
609
- const handleLocalNavigation = (path) => {
610
- const sanitizedPath = sanitizeEmbeddedAppPath(path);
611
- if (!sanitizedPath) {
612
- return;
613
- }
614
- onNavigateRef.current?.(sanitizedPath);
615
- };
616
- const handleDocumentClick = (event) => {
617
- if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) {
618
- return;
619
- }
620
- const target = event.target;
621
- if (!(target instanceof Element)) {
622
- return;
623
- }
624
- const anchor = target.closest("a[href]");
625
- if (!(anchor instanceof HTMLAnchorElement)) {
626
- return;
627
- }
628
- if (anchor.hasAttribute("download")) {
629
- return;
630
- }
631
- const targetWindow2 = anchor.target.toLowerCase();
632
- const href = anchor.getAttribute("href");
633
- if (!href) {
634
- return;
635
- }
636
- if (targetWindow2 === "_top" || targetWindow2 === "_parent") {
637
- event.preventDefault();
638
- bridge.redirectToRemote(anchor.href);
639
- return;
640
- }
641
- if (targetWindow2 && targetWindow2 !== "_self") {
642
- return;
643
- }
644
- const nextPath = resolveLocalNavigationPath(href, window.location.origin);
645
- if (!nextPath) {
646
- return;
647
- }
648
- event.preventDefault();
649
- handleLocalNavigation(nextPath);
650
- };
651
- const originalOpen = window.open.bind(window);
652
- window.open = (url, target, features) => {
653
- if (url == null) {
654
- return originalOpen(url, target, features);
655
- }
656
- const href = typeof url === "string" ? url : url.toString();
657
- const targetName = (target ?? "").toLowerCase();
658
- if (targetName === "_top" || targetName === "_parent") {
659
- bridge.redirectToRemote(new URL(href, window.location.href).toString());
660
- return null;
544
+ this.removeNavigationInterceptors = installNavigationInterceptors({
545
+ bridge: this.bridge,
546
+ selfWindow: this.selfWindow,
547
+ navigate: (path) => this.navigate(path)
548
+ });
549
+ this.restoreFetch = installFetchInterceptor({
550
+ bridge: this.bridge,
551
+ getClientId: () => this.clientId,
552
+ getProject: () => this.project,
553
+ setProject: (project) => {
554
+ this.project = project;
555
+ },
556
+ readCachedToken: () => this.sessionTokenCache,
557
+ writeCachedToken: (token) => {
558
+ this.sessionTokenCache = token;
559
+ },
560
+ readPendingToken: () => this.pendingSessionToken,
561
+ writePendingToken: (token) => {
562
+ this.pendingSessionToken = token;
661
563
  }
662
- if (!targetName || targetName === "_self") {
663
- const nextPath = resolveLocalNavigationPath(href, window.location.origin);
664
- if (nextPath) {
665
- handleLocalNavigation(nextPath);
666
- return window;
667
- }
564
+ });
565
+ this.update(config);
566
+ }
567
+ update(config) {
568
+ if (config.clientId) {
569
+ this.clientId = config.clientId;
570
+ if (!this.readyPayload || typeof this.readyPayload === "object" && this.readyPayload !== null && "clientId" in this.readyPayload) {
571
+ this.readyPayload = config.readyPayload ?? { clientId: config.clientId };
668
572
  }
669
- return originalOpen(url, target, features);
670
- };
671
- document.addEventListener("click", handleDocumentClick, true);
672
- return () => {
673
- document.removeEventListener("click", handleDocumentClick, true);
674
- window.open = originalOpen;
675
- };
676
- }, [bridge, onNavigate]);
677
- useEffect(() => {
678
- if (!bridge || typeof window === "undefined") {
573
+ }
574
+ if (config.currentPath !== void 0) {
575
+ this.currentPath = config.currentPath;
576
+ }
577
+ if (config.navigationItems !== void 0) {
578
+ this.navigationItems = normalizeBridgeNavigationItems(config.navigationItems);
579
+ }
580
+ if (config.onNavigate !== void 0) {
581
+ this.onNavigate = config.onNavigate;
582
+ }
583
+ if (config.readyEventType) {
584
+ this.readyEventType = config.readyEventType;
585
+ }
586
+ if (config.readyPayload !== void 0) {
587
+ this.readyPayload = config.readyPayload;
588
+ }
589
+ if (config.targetWindow !== void 0) {
590
+ this.bridge.setTargetWindow(config.targetWindow ?? null);
591
+ }
592
+ this.syncBridgeState();
593
+ }
594
+ clearNavigationHandler() {
595
+ this.onNavigate = void 0;
596
+ }
597
+ destroy() {
598
+ this.removeNavigationRequestHandler?.();
599
+ this.removeNavigationInterceptors();
600
+ this.restoreFetch();
601
+ this.bridge.destroy();
602
+ }
603
+ syncBridgeState() {
604
+ if (!this.bridge.hasTargetWindow()) {
679
605
  return;
680
606
  }
681
- const originalFetch = globalThis.fetch.bind(globalThis);
682
- const interceptedFetch = async (input, init) => {
683
- if (!shouldAttachSessionToken(input)) {
684
- return originalFetch(input, init);
685
- }
686
- const existingAuthorization = getExistingAuthorization(input, init);
687
- if (existingAuthorization) {
688
- return originalFetch(input, init);
689
- }
690
- const nextHeaders = new Headers(
691
- input instanceof Request ? input.headers : init?.headers
607
+ this.bridge.send(this.readyEventType, this.readyPayload);
608
+ this.bridge.send("navigation:items:update", {
609
+ items: this.navigationItems
610
+ });
611
+ if (this.currentPath) {
612
+ this.bridge.send(
613
+ this.navigationUpdateEventType,
614
+ buildNavigationUpdatePayload(this.currentPath)
692
615
  );
693
- if (projectRef.current && !nextHeaders.has("X-Thor-Project")) {
694
- nextHeaders.set("X-Thor-Project", projectRef.current);
695
- }
696
- try {
697
- const sessionToken = await getSessionToken({
698
- bridge,
699
- clientId,
700
- pendingSessionTokenRef,
701
- projectRef,
702
- sessionTokenCacheRef
703
- });
704
- nextHeaders.set("Authorization", `Bearer ${sessionToken}`);
705
- } catch {
706
- if (!projectRef.current) {
707
- throw new Error("Missing Thor embedded session token");
708
- }
709
- }
710
- if (!nextHeaders.has("X-Requested-With")) {
711
- nextHeaders.set("X-Requested-With", "XMLHttpRequest");
712
- }
713
- if (input instanceof Request) {
714
- return originalFetch(
715
- new Request(input, {
716
- headers: nextHeaders
717
- })
718
- );
719
- }
720
- return originalFetch(input, {
721
- ...init,
722
- headers: nextHeaders
723
- });
724
- };
725
- globalThis.fetch = interceptedFetch;
726
- window.fetch = interceptedFetch;
727
- return () => {
728
- globalThis.fetch = originalFetch;
729
- window.fetch = originalFetch;
730
- };
731
- }, [bridge, clientId]);
732
- return /* @__PURE__ */ jsx(AppBridgeContext.Provider, { value: bridge, children });
616
+ }
617
+ }
618
+ navigate(path, message) {
619
+ if (this.onNavigate) {
620
+ this.onNavigate(path, message);
621
+ return;
622
+ }
623
+ if (dispatchNavigateEvent(this.selfWindow.document, path)) {
624
+ return;
625
+ }
626
+ this.selfWindow.location.assign(path);
627
+ }
628
+ };
629
+ function getOrCreateEmbeddedAppRuntime(config) {
630
+ const globalScope = globalThis;
631
+ const existingRuntime = globalScope[GLOBAL_RUNTIME_KEY];
632
+ if (existingRuntime) {
633
+ existingRuntime.update(config);
634
+ return existingRuntime;
635
+ }
636
+ const runtime = new EmbeddedAppRuntime(config);
637
+ globalScope[GLOBAL_RUNTIME_KEY] = runtime;
638
+ return runtime;
733
639
  }
734
- function useAppBridge() {
735
- return useContext(AppBridgeContext);
640
+ function getEmbeddedAppRuntime() {
641
+ return globalThis[GLOBAL_RUNTIME_KEY] ?? null;
642
+ }
643
+ function dispatchNavigateEvent(document, path) {
644
+ const event = new CustomEvent(THOR_NAVIGATE_EVENT, {
645
+ cancelable: true,
646
+ detail: { path }
647
+ });
648
+ document.dispatchEvent(event);
649
+ return event.defaultPrevented;
736
650
  }
737
651
  function getReferrerOrigin(explicitWindow) {
738
652
  const resolvedWindow = explicitWindow ?? (typeof window !== "undefined" ? window : void 0);
@@ -746,40 +660,190 @@ function getReferrerOrigin(explicitWindow) {
746
660
  return void 0;
747
661
  }
748
662
  }
663
+ function installNavigationInterceptors({
664
+ bridge,
665
+ selfWindow,
666
+ navigate
667
+ }) {
668
+ const document = selfWindow.document;
669
+ const handleLocalNavigation = (path) => {
670
+ const sanitizedPath = sanitizeEmbeddedAppPath(path);
671
+ if (!sanitizedPath) {
672
+ return;
673
+ }
674
+ const nextPath = preserveEmbeddedAppLaunchParams(
675
+ sanitizedPath,
676
+ selfWindow.location.href
677
+ );
678
+ navigate(nextPath ?? sanitizedPath);
679
+ };
680
+ const handleDocumentClick = (event) => {
681
+ if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) {
682
+ return;
683
+ }
684
+ const target = event.target;
685
+ if (!(target instanceof Element)) {
686
+ return;
687
+ }
688
+ const anchor = target.closest("a[href]");
689
+ if (!(anchor instanceof HTMLAnchorElement)) {
690
+ return;
691
+ }
692
+ if (anchor.hasAttribute("download")) {
693
+ return;
694
+ }
695
+ const targetWindow = anchor.target.toLowerCase();
696
+ const href = anchor.getAttribute("href");
697
+ if (!href) {
698
+ return;
699
+ }
700
+ if (targetWindow === "_top" || targetWindow === "_parent") {
701
+ event.preventDefault();
702
+ bridge.redirectToRemote(anchor.href);
703
+ return;
704
+ }
705
+ if (targetWindow && targetWindow !== "_self") {
706
+ return;
707
+ }
708
+ const nextPath = resolveLocalNavigationPath(href, selfWindow.location.origin);
709
+ if (!nextPath) {
710
+ return;
711
+ }
712
+ event.preventDefault();
713
+ handleLocalNavigation(nextPath);
714
+ };
715
+ const originalOpen = selfWindow.open.bind(selfWindow);
716
+ selfWindow.open = (url, target, features) => {
717
+ if (url == null) {
718
+ return originalOpen(url, target, features);
719
+ }
720
+ const href = typeof url === "string" ? url : url.toString();
721
+ const targetName = (target ?? "").toLowerCase();
722
+ if (targetName === "_top" || targetName === "_parent") {
723
+ bridge.redirectToRemote(new URL(href, selfWindow.location.href).toString());
724
+ return null;
725
+ }
726
+ if (!targetName || targetName === "_self") {
727
+ const nextPath = resolveLocalNavigationPath(
728
+ href,
729
+ selfWindow.location.origin
730
+ );
731
+ if (nextPath) {
732
+ handleLocalNavigation(nextPath);
733
+ return selfWindow;
734
+ }
735
+ }
736
+ return originalOpen(url, target, features);
737
+ };
738
+ document.addEventListener("click", handleDocumentClick, true);
739
+ return () => {
740
+ document.removeEventListener("click", handleDocumentClick, true);
741
+ selfWindow.open = originalOpen;
742
+ };
743
+ }
744
+ function installFetchInterceptor({
745
+ bridge,
746
+ getClientId,
747
+ getProject,
748
+ setProject,
749
+ readCachedToken,
750
+ writeCachedToken,
751
+ readPendingToken,
752
+ writePendingToken
753
+ }) {
754
+ if (typeof window === "undefined") {
755
+ return () => {
756
+ };
757
+ }
758
+ const originalFetch = globalThis.fetch.bind(globalThis);
759
+ const interceptedFetch = async (input, init) => {
760
+ if (!shouldAttachSessionToken(input)) {
761
+ return originalFetch(input, init);
762
+ }
763
+ const existingAuthorization = getExistingAuthorization(input, init);
764
+ if (existingAuthorization) {
765
+ return originalFetch(input, init);
766
+ }
767
+ const nextHeaders = new Headers(
768
+ input instanceof Request ? input.headers : init?.headers
769
+ );
770
+ try {
771
+ const sessionToken = await getSessionToken({
772
+ bridge,
773
+ clientId: getClientId(),
774
+ project: getProject,
775
+ setProject,
776
+ readCachedToken,
777
+ writeCachedToken,
778
+ readPendingToken,
779
+ writePendingToken
780
+ });
781
+ nextHeaders.set("Authorization", `Bearer ${sessionToken}`);
782
+ } catch {
783
+ if (!getProject()) {
784
+ throw new Error("Missing Thor embedded session token");
785
+ }
786
+ }
787
+ if (!nextHeaders.has("X-Requested-With")) {
788
+ nextHeaders.set("X-Requested-With", "XMLHttpRequest");
789
+ }
790
+ if (input instanceof Request) {
791
+ return originalFetch(
792
+ new Request(input, {
793
+ headers: nextHeaders
794
+ })
795
+ );
796
+ }
797
+ return originalFetch(input, {
798
+ ...init,
799
+ headers: nextHeaders
800
+ });
801
+ };
802
+ globalThis.fetch = interceptedFetch;
803
+ window.fetch = interceptedFetch;
804
+ return () => {
805
+ globalThis.fetch = originalFetch;
806
+ window.fetch = originalFetch;
807
+ };
808
+ }
749
809
  async function getSessionToken({
750
810
  bridge,
751
811
  clientId,
752
- pendingSessionTokenRef,
753
- projectRef,
754
- sessionTokenCacheRef
812
+ project,
813
+ setProject,
814
+ readCachedToken,
815
+ writeCachedToken,
816
+ readPendingToken,
817
+ writePendingToken
755
818
  }) {
756
- const cachedToken = sessionTokenCacheRef.current;
819
+ const cachedToken = readCachedToken();
757
820
  if (cachedToken && !isExpired(cachedToken.expiresAt)) {
758
821
  return cachedToken.token;
759
822
  }
760
- if (pendingSessionTokenRef.current) {
761
- return pendingSessionTokenRef.current;
823
+ const pendingToken = readPendingToken();
824
+ if (pendingToken) {
825
+ return pendingToken;
762
826
  }
763
- const pendingToken = bridge.getSessionToken({ clientId }).then((response) => {
827
+ const nextPendingToken = bridge.getSessionToken({ clientId }).then((response) => {
764
828
  const token = response.sessionToken ?? response.idToken;
765
829
  if (!token) {
766
830
  throw new Error("Missing Thor embedded session token");
767
831
  }
768
832
  if (response.project) {
769
- projectRef.current = response.project;
833
+ setProject(response.project);
770
834
  }
771
- sessionTokenCacheRef.current = {
835
+ writeCachedToken({
772
836
  token,
773
837
  expiresAt: normalizeTokenExpiry(token, response.exp)
774
- };
775
- pendingSessionTokenRef.current = null;
838
+ });
839
+ writePendingToken(null);
776
840
  return token;
777
841
  }).catch((error) => {
778
- pendingSessionTokenRef.current = null;
842
+ writePendingToken(null);
779
843
  throw error;
780
844
  });
781
- pendingSessionTokenRef.current = pendingToken;
782
- return pendingToken;
845
+ writePendingToken(nextPendingToken);
846
+ return nextPendingToken;
783
847
  }
784
848
  function shouldAttachSessionToken(input) {
785
849
  if (typeof window === "undefined") {
@@ -850,6 +914,7 @@ export {
850
914
  EMBEDDED_LAUNCH_PARAMS,
851
915
  buildNavigationUpdatePayload,
852
916
  sanitizeEmbeddedAppPath,
917
+ preserveEmbeddedAppLaunchParams,
853
918
  resolveLocalNavigationPath,
854
919
  resolveNavigationDestination,
855
920
  normalizeBridgeNavigationItem,
@@ -857,7 +922,9 @@ export {
857
922
  isBridgeMessage,
858
923
  AppBridge,
859
924
  createAppBridge,
860
- AppBridgeProvider,
861
- useAppBridge
925
+ THOR_NAVIGATE_EVENT,
926
+ EmbeddedAppRuntime,
927
+ getOrCreateEmbeddedAppRuntime,
928
+ getEmbeddedAppRuntime
862
929
  };
863
- //# sourceMappingURL=chunk-XPUL72AN.js.map
930
+ //# sourceMappingURL=chunk-IRTDLWEQ.js.map