@thor-commerce/app-bridge-react 0.7.3 → 0.9.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.
@@ -530,240 +530,214 @@ function createAppBridge(options = {}) {
530
530
  return new AppBridge(options);
531
531
  }
532
532
 
533
- // src/react.tsx
534
- var import_jsx_runtime = require("react/jsx-runtime");
535
- var AppBridgeContext = (0, import_react.createContext)(null);
536
- function AppBridgeProvider({
537
- children,
538
- clientId,
539
- currentPath,
540
- navigationItems,
541
- navigationEventType = "navigation:go",
542
- navigationUpdateEventType = "navigation:update",
543
- namespace,
544
- onNavigate,
545
- readyEventType = "app:ready",
546
- readyPayload,
547
- requestTimeoutMs,
548
- selfWindow,
549
- targetOrigin,
550
- targetWindow
551
- }) {
552
- const [bridge, setBridge] = (0, import_react.useState)(null);
553
- const onNavigateRef = (0, import_react.useRef)(onNavigate);
554
- const normalizedNavigationItems = (0, import_react.useMemo)(
555
- () => normalizeBridgeNavigationItems(navigationItems),
556
- [navigationItems]
557
- );
558
- const sessionTokenCacheRef = (0, import_react.useRef)(null);
559
- const projectRef = (0, import_react.useRef)(readInitialProject(selfWindow));
560
- const pendingSessionTokenRef = (0, import_react.useRef)(null);
561
- (0, import_react.useEffect)(() => {
562
- onNavigateRef.current = onNavigate;
563
- }, [onNavigate]);
564
- (0, import_react.useEffect)(() => {
565
- if (typeof window === "undefined" && !selfWindow) {
566
- return;
533
+ // src/runtime.ts
534
+ var GLOBAL_RUNTIME_KEY = "__thorEmbeddedAppRuntime__";
535
+ var THOR_NAVIGATE_EVENT = "thor:navigate";
536
+ var EmbeddedAppRuntime = class {
537
+ constructor(config) {
538
+ this.currentPath = null;
539
+ this.navigationItems = [];
540
+ this.navigationEventType = "navigation:go";
541
+ this.navigationUpdateEventType = "navigation:update";
542
+ this.readyEventType = "app:ready";
543
+ this.hasSentReady = false;
544
+ this.lastSentNavigationItemsKey = null;
545
+ this.lastReportedPath = null;
546
+ this.pendingHostNavigationPath = null;
547
+ this.sessionTokenCache = null;
548
+ this.pendingSessionToken = null;
549
+ const resolvedWindow = config.selfWindow ?? (typeof window !== "undefined" ? window : void 0);
550
+ if (!resolvedWindow) {
551
+ throw new Error("EmbeddedAppRuntime requires a browser window.");
567
552
  }
568
- const resolvedTargetOrigin = targetOrigin ?? getReferrerOrigin(selfWindow);
569
- const resolvedAllowedOrigins = resolvedTargetOrigin ? [resolvedTargetOrigin] : void 0;
570
- const nextBridge = createAppBridge({
571
- allowedOrigins: resolvedAllowedOrigins,
572
- clientId,
573
- namespace,
574
- requestTimeoutMs,
575
- selfWindow,
553
+ this.selfWindow = resolvedWindow;
554
+ this.targetOrigin = config.targetOrigin ?? getReferrerOrigin(resolvedWindow);
555
+ this.clientId = config.clientId;
556
+ this.currentPath = readCurrentPath(resolvedWindow);
557
+ this.project = readInitialProject(resolvedWindow);
558
+ this.readyPayload = config.readyPayload ?? { clientId: config.clientId };
559
+ this.bridge = createAppBridge({
560
+ allowedOrigins: this.targetOrigin ? [this.targetOrigin] : void 0,
561
+ namespace: config.namespace,
562
+ requestTimeoutMs: config.requestTimeoutMs,
563
+ selfWindow: resolvedWindow,
576
564
  source: "embedded-app",
577
565
  target: "dashboard",
578
- targetOrigin: resolvedTargetOrigin,
579
- targetWindow
566
+ targetOrigin: this.targetOrigin,
567
+ targetWindow: config.targetWindow
580
568
  });
581
- setBridge(nextBridge);
582
- return () => {
583
- setBridge((currentBridge) => currentBridge === nextBridge ? null : currentBridge);
584
- nextBridge.destroy();
585
- };
586
- }, [
587
- clientId,
588
- namespace,
589
- requestTimeoutMs,
590
- selfWindow,
591
- targetOrigin,
592
- targetWindow
593
- ]);
594
- (0, import_react.useEffect)(() => {
595
- if (!bridge || !bridge.hasTargetWindow()) {
596
- return;
597
- }
598
- bridge.send(
599
- readyEventType,
600
- readyPayload ?? {
601
- clientId
602
- }
603
- );
604
- }, [bridge, clientId, readyEventType, readyPayload]);
605
- (0, import_react.useEffect)(() => {
606
- if (!bridge || !bridge.hasTargetWindow()) {
607
- return;
608
- }
609
- bridge.send("navigation:items:update", {
610
- items: normalizedNavigationItems
611
- });
612
- }, [bridge, normalizedNavigationItems]);
613
- (0, import_react.useEffect)(() => {
614
- if (!bridge || !bridge.hasTargetWindow() || !currentPath) {
615
- return;
616
- }
617
- bridge.send(navigationUpdateEventType, buildNavigationUpdatePayload(currentPath));
618
- }, [bridge, currentPath, navigationUpdateEventType]);
619
- (0, import_react.useEffect)(() => {
620
- if (!bridge || !onNavigate) {
621
- return;
622
- }
623
- return bridge.on(navigationEventType, (message) => {
569
+ this.removeNavigationRequestHandler = this.bridge.on(this.navigationEventType, (message) => {
624
570
  const destination = resolveNavigationDestination(message.payload);
625
571
  if (!destination) {
626
572
  return;
627
573
  }
574
+ this.pendingHostNavigationPath = sanitizeEmbeddedAppPath(destination) ?? destination;
628
575
  const nextPath = preserveEmbeddedAppLaunchParams(
629
576
  destination,
630
- typeof window !== "undefined" ? window.location.href : void 0
577
+ this.selfWindow.location.href
631
578
  );
632
- onNavigateRef.current?.(nextPath ?? destination, message);
579
+ this.navigate(nextPath ?? destination, message);
633
580
  });
634
- }, [bridge, navigationEventType, onNavigate]);
635
- (0, import_react.useEffect)(() => {
636
- if (!bridge || !onNavigate || typeof document === "undefined" || typeof window === "undefined") {
637
- return;
638
- }
639
- const handleLocalNavigation = (path) => {
640
- const sanitizedPath = sanitizeEmbeddedAppPath(path);
641
- if (!sanitizedPath) {
642
- return;
643
- }
644
- const nextPath = preserveEmbeddedAppLaunchParams(
645
- sanitizedPath,
646
- window.location.href
647
- );
648
- onNavigateRef.current?.(nextPath ?? sanitizedPath);
649
- };
650
- const handleDocumentClick = (event) => {
651
- if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) {
652
- return;
653
- }
654
- const target = event.target;
655
- if (!(target instanceof Element)) {
656
- return;
657
- }
658
- const anchor = target.closest("a[href]");
659
- if (!(anchor instanceof HTMLAnchorElement)) {
660
- return;
661
- }
662
- if (anchor.hasAttribute("download")) {
663
- return;
581
+ this.removeNavigationInterceptors = installNavigationInterceptors({
582
+ bridge: this.bridge,
583
+ selfWindow: this.selfWindow,
584
+ navigate: (path) => this.navigate(path)
585
+ });
586
+ this.removeHistoryObserver = installHistoryObserver({
587
+ selfWindow: this.selfWindow,
588
+ onChange: (path) => {
589
+ this.currentPath = path;
590
+ this.syncBridgeState();
664
591
  }
665
- const targetWindow2 = anchor.target.toLowerCase();
666
- const href = anchor.getAttribute("href");
667
- if (!href) {
668
- return;
592
+ });
593
+ this.restoreFetch = installFetchInterceptor({
594
+ bridge: this.bridge,
595
+ getClientId: () => this.clientId,
596
+ getProject: () => this.project,
597
+ setProject: (project) => {
598
+ this.project = project;
599
+ },
600
+ readCachedToken: () => this.sessionTokenCache,
601
+ writeCachedToken: (token) => {
602
+ this.sessionTokenCache = token;
603
+ },
604
+ readPendingToken: () => this.pendingSessionToken,
605
+ writePendingToken: (token) => {
606
+ this.pendingSessionToken = token;
669
607
  }
670
- if (targetWindow2 === "_top" || targetWindow2 === "_parent") {
671
- event.preventDefault();
672
- bridge.redirectToRemote(anchor.href);
673
- return;
608
+ });
609
+ this.update(config);
610
+ }
611
+ update(config) {
612
+ if (config.clientId) {
613
+ this.clientId = config.clientId;
614
+ if (!this.readyPayload || typeof this.readyPayload === "object" && this.readyPayload !== null && "clientId" in this.readyPayload) {
615
+ this.readyPayload = config.readyPayload ?? { clientId: config.clientId };
674
616
  }
675
- if (targetWindow2 && targetWindow2 !== "_self") {
617
+ }
618
+ if (config.currentPath !== void 0) {
619
+ this.currentPath = config.currentPath;
620
+ }
621
+ if (config.navigationItems !== void 0) {
622
+ this.navigationItems = normalizeBridgeNavigationItems(config.navigationItems);
623
+ }
624
+ if (config.onNavigate !== void 0) {
625
+ this.onNavigate = config.onNavigate;
626
+ }
627
+ if (config.readyEventType) {
628
+ this.readyEventType = config.readyEventType;
629
+ }
630
+ if (config.readyPayload !== void 0) {
631
+ this.readyPayload = config.readyPayload;
632
+ }
633
+ if (config.targetWindow !== void 0) {
634
+ this.bridge.setTargetWindow(config.targetWindow ?? null);
635
+ }
636
+ this.syncBridgeState();
637
+ }
638
+ clearNavigationHandler() {
639
+ this.onNavigate = void 0;
640
+ }
641
+ destroy() {
642
+ this.removeNavigationRequestHandler?.();
643
+ this.removeNavigationInterceptors();
644
+ this.removeHistoryObserver();
645
+ this.restoreFetch();
646
+ this.bridge.destroy();
647
+ }
648
+ syncBridgeState() {
649
+ if (!this.bridge.hasTargetWindow()) {
650
+ return;
651
+ }
652
+ if (!this.hasSentReady) {
653
+ this.bridge.send(this.readyEventType, this.readyPayload);
654
+ this.hasSentReady = true;
655
+ }
656
+ const navigationItemsKey = JSON.stringify(this.navigationItems);
657
+ if (navigationItemsKey !== this.lastSentNavigationItemsKey) {
658
+ this.bridge.send("navigation:items:update", {
659
+ items: this.navigationItems
660
+ });
661
+ this.lastSentNavigationItemsKey = navigationItemsKey;
662
+ }
663
+ if (this.currentPath) {
664
+ if (this.currentPath === this.pendingHostNavigationPath) {
665
+ this.pendingHostNavigationPath = null;
666
+ this.lastReportedPath = this.currentPath;
676
667
  return;
677
668
  }
678
- const nextPath = resolveLocalNavigationPath(href, window.location.origin);
679
- if (!nextPath) {
669
+ if (this.currentPath === this.lastReportedPath) {
680
670
  return;
681
671
  }
682
- event.preventDefault();
683
- handleLocalNavigation(nextPath);
684
- };
685
- const originalOpen = window.open.bind(window);
686
- window.open = (url, target, features) => {
687
- if (url == null) {
688
- return originalOpen(url, target, features);
689
- }
690
- const href = typeof url === "string" ? url : url.toString();
691
- const targetName = (target ?? "").toLowerCase();
692
- if (targetName === "_top" || targetName === "_parent") {
693
- bridge.redirectToRemote(new URL(href, window.location.href).toString());
694
- return null;
695
- }
696
- if (!targetName || targetName === "_self") {
697
- const nextPath = resolveLocalNavigationPath(href, window.location.origin);
698
- if (nextPath) {
699
- handleLocalNavigation(nextPath);
700
- return window;
701
- }
702
- }
703
- return originalOpen(url, target, features);
704
- };
705
- document.addEventListener("click", handleDocumentClick, true);
706
- return () => {
707
- document.removeEventListener("click", handleDocumentClick, true);
708
- window.open = originalOpen;
709
- };
710
- }, [bridge, onNavigate]);
711
- (0, import_react.useEffect)(() => {
712
- if (!bridge || typeof window === "undefined") {
672
+ this.bridge.send(
673
+ this.navigationUpdateEventType,
674
+ buildNavigationUpdatePayload(this.currentPath)
675
+ );
676
+ this.lastReportedPath = this.currentPath;
677
+ }
678
+ }
679
+ navigate(path, message) {
680
+ if (this.onNavigate) {
681
+ this.onNavigate(path, message);
713
682
  return;
714
683
  }
715
- const originalFetch = globalThis.fetch.bind(globalThis);
716
- const interceptedFetch = async (input, init) => {
717
- if (!shouldAttachSessionToken(input)) {
718
- return originalFetch(input, init);
719
- }
720
- const existingAuthorization = getExistingAuthorization(input, init);
721
- if (existingAuthorization) {
722
- return originalFetch(input, init);
723
- }
724
- const nextHeaders = new Headers(
725
- input instanceof Request ? input.headers : init?.headers
726
- );
727
- if (projectRef.current && !nextHeaders.has("X-Thor-Project")) {
728
- nextHeaders.set("X-Thor-Project", projectRef.current);
729
- }
730
- try {
731
- const sessionToken = await getSessionToken({
732
- bridge,
733
- clientId,
734
- pendingSessionTokenRef,
735
- projectRef,
736
- sessionTokenCacheRef
737
- });
738
- nextHeaders.set("Authorization", `Bearer ${sessionToken}`);
739
- } catch {
740
- if (!projectRef.current) {
741
- throw new Error("Missing Thor embedded session token");
742
- }
743
- }
744
- if (!nextHeaders.has("X-Requested-With")) {
745
- nextHeaders.set("X-Requested-With", "XMLHttpRequest");
746
- }
747
- if (input instanceof Request) {
748
- return originalFetch(
749
- new Request(input, {
750
- headers: nextHeaders
751
- })
752
- );
753
- }
754
- return originalFetch(input, {
755
- ...init,
756
- headers: nextHeaders
757
- });
758
- };
759
- globalThis.fetch = interceptedFetch;
760
- window.fetch = interceptedFetch;
761
- return () => {
762
- globalThis.fetch = originalFetch;
763
- window.fetch = originalFetch;
764
- };
765
- }, [bridge, clientId]);
766
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppBridgeContext.Provider, { value: bridge, children });
684
+ if (dispatchNavigateEvent(this.selfWindow.document, path)) {
685
+ return;
686
+ }
687
+ this.selfWindow.location.assign(path);
688
+ }
689
+ };
690
+ function getOrCreateEmbeddedAppRuntime(config) {
691
+ const globalScope = globalThis;
692
+ const existingRuntime = globalScope[GLOBAL_RUNTIME_KEY];
693
+ if (existingRuntime) {
694
+ existingRuntime.update(config);
695
+ return existingRuntime;
696
+ }
697
+ const runtime = new EmbeddedAppRuntime(config);
698
+ globalScope[GLOBAL_RUNTIME_KEY] = runtime;
699
+ return runtime;
700
+ }
701
+ function dispatchNavigateEvent(document, path) {
702
+ const event = new CustomEvent(THOR_NAVIGATE_EVENT, {
703
+ cancelable: true,
704
+ detail: { path }
705
+ });
706
+ document.dispatchEvent(event);
707
+ return event.defaultPrevented;
708
+ }
709
+ function readCurrentPath(selfWindow) {
710
+ return sanitizeEmbeddedAppPath(
711
+ `${selfWindow.location.pathname}${selfWindow.location.search}${selfWindow.location.hash}`
712
+ ) ?? null;
713
+ }
714
+ function installHistoryObserver({
715
+ selfWindow,
716
+ onChange
717
+ }) {
718
+ const history = selfWindow.history;
719
+ const originalPushState = history.pushState;
720
+ const originalReplaceState = history.replaceState;
721
+ const notify = () => {
722
+ onChange(readCurrentPath(selfWindow));
723
+ };
724
+ history.pushState = function(...args) {
725
+ originalPushState.apply(history, args);
726
+ notify();
727
+ };
728
+ history.replaceState = function(...args) {
729
+ originalReplaceState.apply(history, args);
730
+ notify();
731
+ };
732
+ selfWindow.addEventListener("popstate", notify);
733
+ selfWindow.addEventListener("hashchange", notify);
734
+ notify();
735
+ return () => {
736
+ history.pushState = originalPushState;
737
+ history.replaceState = originalReplaceState;
738
+ selfWindow.removeEventListener("popstate", notify);
739
+ selfWindow.removeEventListener("hashchange", notify);
740
+ };
767
741
  }
768
742
  function getReferrerOrigin(explicitWindow) {
769
743
  const resolvedWindow = explicitWindow ?? (typeof window !== "undefined" ? window : void 0);
@@ -777,40 +751,190 @@ function getReferrerOrigin(explicitWindow) {
777
751
  return void 0;
778
752
  }
779
753
  }
754
+ function installNavigationInterceptors({
755
+ bridge,
756
+ selfWindow,
757
+ navigate
758
+ }) {
759
+ const document = selfWindow.document;
760
+ const handleLocalNavigation = (path) => {
761
+ const sanitizedPath = sanitizeEmbeddedAppPath(path);
762
+ if (!sanitizedPath) {
763
+ return;
764
+ }
765
+ const nextPath = preserveEmbeddedAppLaunchParams(
766
+ sanitizedPath,
767
+ selfWindow.location.href
768
+ );
769
+ navigate(nextPath ?? sanitizedPath);
770
+ };
771
+ const handleDocumentClick = (event) => {
772
+ if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) {
773
+ return;
774
+ }
775
+ const target = event.target;
776
+ if (!(target instanceof Element)) {
777
+ return;
778
+ }
779
+ const anchor = target.closest("a[href]");
780
+ if (!(anchor instanceof HTMLAnchorElement)) {
781
+ return;
782
+ }
783
+ if (anchor.hasAttribute("download")) {
784
+ return;
785
+ }
786
+ const targetWindow = anchor.target.toLowerCase();
787
+ const href = anchor.getAttribute("href");
788
+ if (!href) {
789
+ return;
790
+ }
791
+ if (targetWindow === "_top" || targetWindow === "_parent") {
792
+ event.preventDefault();
793
+ bridge.redirectToRemote(anchor.href);
794
+ return;
795
+ }
796
+ if (targetWindow && targetWindow !== "_self") {
797
+ return;
798
+ }
799
+ const nextPath = resolveLocalNavigationPath(href, selfWindow.location.origin);
800
+ if (!nextPath) {
801
+ return;
802
+ }
803
+ event.preventDefault();
804
+ handleLocalNavigation(nextPath);
805
+ };
806
+ const originalOpen = selfWindow.open.bind(selfWindow);
807
+ selfWindow.open = (url, target, features) => {
808
+ if (url == null) {
809
+ return originalOpen(url, target, features);
810
+ }
811
+ const href = typeof url === "string" ? url : url.toString();
812
+ const targetName = (target ?? "").toLowerCase();
813
+ if (targetName === "_top" || targetName === "_parent") {
814
+ bridge.redirectToRemote(new URL(href, selfWindow.location.href).toString());
815
+ return null;
816
+ }
817
+ if (!targetName || targetName === "_self") {
818
+ const nextPath = resolveLocalNavigationPath(
819
+ href,
820
+ selfWindow.location.origin
821
+ );
822
+ if (nextPath) {
823
+ handleLocalNavigation(nextPath);
824
+ return selfWindow;
825
+ }
826
+ }
827
+ return originalOpen(url, target, features);
828
+ };
829
+ document.addEventListener("click", handleDocumentClick, true);
830
+ return () => {
831
+ document.removeEventListener("click", handleDocumentClick, true);
832
+ selfWindow.open = originalOpen;
833
+ };
834
+ }
835
+ function installFetchInterceptor({
836
+ bridge,
837
+ getClientId,
838
+ getProject,
839
+ setProject,
840
+ readCachedToken,
841
+ writeCachedToken,
842
+ readPendingToken,
843
+ writePendingToken
844
+ }) {
845
+ if (typeof window === "undefined") {
846
+ return () => {
847
+ };
848
+ }
849
+ const originalFetch = globalThis.fetch.bind(globalThis);
850
+ const interceptedFetch = async (input, init) => {
851
+ if (!shouldAttachSessionToken(input)) {
852
+ return originalFetch(input, init);
853
+ }
854
+ const existingAuthorization = getExistingAuthorization(input, init);
855
+ if (existingAuthorization) {
856
+ return originalFetch(input, init);
857
+ }
858
+ const nextHeaders = new Headers(
859
+ input instanceof Request ? input.headers : init?.headers
860
+ );
861
+ try {
862
+ const sessionToken = await getSessionToken({
863
+ bridge,
864
+ clientId: getClientId(),
865
+ project: getProject,
866
+ setProject,
867
+ readCachedToken,
868
+ writeCachedToken,
869
+ readPendingToken,
870
+ writePendingToken
871
+ });
872
+ nextHeaders.set("Authorization", `Bearer ${sessionToken}`);
873
+ } catch {
874
+ if (!getProject()) {
875
+ throw new Error("Missing Thor embedded session token");
876
+ }
877
+ }
878
+ if (!nextHeaders.has("X-Requested-With")) {
879
+ nextHeaders.set("X-Requested-With", "XMLHttpRequest");
880
+ }
881
+ if (input instanceof Request) {
882
+ return originalFetch(
883
+ new Request(input, {
884
+ headers: nextHeaders
885
+ })
886
+ );
887
+ }
888
+ return originalFetch(input, {
889
+ ...init,
890
+ headers: nextHeaders
891
+ });
892
+ };
893
+ globalThis.fetch = interceptedFetch;
894
+ window.fetch = interceptedFetch;
895
+ return () => {
896
+ globalThis.fetch = originalFetch;
897
+ window.fetch = originalFetch;
898
+ };
899
+ }
780
900
  async function getSessionToken({
781
901
  bridge,
782
902
  clientId,
783
- pendingSessionTokenRef,
784
- projectRef,
785
- sessionTokenCacheRef
903
+ project,
904
+ setProject,
905
+ readCachedToken,
906
+ writeCachedToken,
907
+ readPendingToken,
908
+ writePendingToken
786
909
  }) {
787
- const cachedToken = sessionTokenCacheRef.current;
910
+ const cachedToken = readCachedToken();
788
911
  if (cachedToken && !isExpired(cachedToken.expiresAt)) {
789
912
  return cachedToken.token;
790
913
  }
791
- if (pendingSessionTokenRef.current) {
792
- return pendingSessionTokenRef.current;
914
+ const pendingToken = readPendingToken();
915
+ if (pendingToken) {
916
+ return pendingToken;
793
917
  }
794
- const pendingToken = bridge.getSessionToken({ clientId }).then((response) => {
918
+ const nextPendingToken = bridge.getSessionToken({ clientId }).then((response) => {
795
919
  const token = response.sessionToken ?? response.idToken;
796
920
  if (!token) {
797
921
  throw new Error("Missing Thor embedded session token");
798
922
  }
799
923
  if (response.project) {
800
- projectRef.current = response.project;
924
+ setProject(response.project);
801
925
  }
802
- sessionTokenCacheRef.current = {
926
+ writeCachedToken({
803
927
  token,
804
928
  expiresAt: normalizeTokenExpiry(token, response.exp)
805
- };
806
- pendingSessionTokenRef.current = null;
929
+ });
930
+ writePendingToken(null);
807
931
  return token;
808
932
  }).catch((error) => {
809
- pendingSessionTokenRef.current = null;
933
+ writePendingToken(null);
810
934
  throw error;
811
935
  });
812
- pendingSessionTokenRef.current = pendingToken;
813
- return pendingToken;
936
+ writePendingToken(nextPendingToken);
937
+ return nextPendingToken;
814
938
  }
815
939
  function shouldAttachSessionToken(input) {
816
940
  if (typeof window === "undefined") {
@@ -877,6 +1001,70 @@ function readInitialProject(explicitWindow) {
877
1001
  }
878
1002
  }
879
1003
 
1004
+ // src/react.tsx
1005
+ var import_jsx_runtime = require("react/jsx-runtime");
1006
+ var AppBridgeContext = (0, import_react.createContext)(null);
1007
+ function AppBridgeProvider({
1008
+ children,
1009
+ clientId,
1010
+ currentPath,
1011
+ navigationItems,
1012
+ navigationEventType = "navigation:go",
1013
+ navigationUpdateEventType = "navigation:update",
1014
+ namespace,
1015
+ onNavigate,
1016
+ readyEventType = "app:ready",
1017
+ readyPayload,
1018
+ requestTimeoutMs,
1019
+ selfWindow,
1020
+ targetOrigin,
1021
+ targetWindow
1022
+ }) {
1023
+ const [bridge, setBridge] = (0, import_react.useState)(null);
1024
+ (0, import_react.useEffect)(() => {
1025
+ if (typeof window === "undefined" && !selfWindow) {
1026
+ return;
1027
+ }
1028
+ const runtime = getOrCreateEmbeddedAppRuntime({
1029
+ clientId,
1030
+ currentPath,
1031
+ navigationEventType,
1032
+ navigationItems,
1033
+ navigationUpdateEventType,
1034
+ namespace,
1035
+ onNavigate,
1036
+ readyEventType,
1037
+ readyPayload,
1038
+ requestTimeoutMs,
1039
+ selfWindow,
1040
+ targetOrigin,
1041
+ targetWindow
1042
+ });
1043
+ setBridge(runtime.bridge);
1044
+ return () => {
1045
+ runtime.clearNavigationHandler();
1046
+ setBridge(
1047
+ (currentBridge) => currentBridge === runtime.bridge ? null : currentBridge
1048
+ );
1049
+ };
1050
+ }, [
1051
+ clientId,
1052
+ currentPath,
1053
+ navigationEventType,
1054
+ navigationItems,
1055
+ navigationUpdateEventType,
1056
+ namespace,
1057
+ onNavigate,
1058
+ readyEventType,
1059
+ readyPayload,
1060
+ requestTimeoutMs,
1061
+ selfWindow,
1062
+ targetOrigin,
1063
+ targetWindow
1064
+ ]);
1065
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppBridgeContext.Provider, { value: bridge, children });
1066
+ }
1067
+
880
1068
  // src/react-router.tsx
881
1069
  var import_jsx_runtime2 = require("react/jsx-runtime");
882
1070
  function ReactRouterAppBridgeProvider({