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