dinocollab-core 2.0.4 → 2.0.6

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.
Files changed (42) hide show
  1. package/dist/components/image-with-fallback.js +1 -1
  2. package/dist/components/image-with-fallback.js.map +1 -1
  3. package/dist/hooks/check-scrolled.js +2 -0
  4. package/dist/hooks/check-scrolled.js.map +1 -0
  5. package/dist/hooks/debounce.js +2 -0
  6. package/dist/hooks/debounce.js.map +1 -0
  7. package/dist/hooks/index.js +1 -1
  8. package/dist/hooks/index.js.map +1 -1
  9. package/dist/hooks/use-fetch-data.js +2 -0
  10. package/dist/hooks/use-fetch-data.js.map +1 -0
  11. package/dist/mfe-shared/auth.debug.js +2 -0
  12. package/dist/mfe-shared/auth.debug.js.map +1 -0
  13. package/dist/mfe-shared/auth.js +1 -1
  14. package/dist/mfe-shared/auth.js.map +1 -1
  15. package/dist/mfe-shared/auth.ssr.js +1 -1
  16. package/dist/mfe-shared/auth.ssr.js.map +1 -1
  17. package/dist/mfe-shared/cart.debug.js +2 -0
  18. package/dist/mfe-shared/cart.debug.js.map +1 -0
  19. package/dist/mfe-shared/cart.js +1 -1
  20. package/dist/mfe-shared/cart.js.map +1 -1
  21. package/dist/mfe-shared/cart.ssr.js +1 -1
  22. package/dist/mfe-shared/cart.ssr.js.map +1 -1
  23. package/dist/mfe-shared/cart.types.js +2 -0
  24. package/dist/mfe-shared/cart.types.js.map +1 -0
  25. package/dist/mfe-shared/index.js +1 -1
  26. package/dist/mfe-shared/navigation.debug.js +2 -0
  27. package/dist/mfe-shared/navigation.debug.js.map +1 -0
  28. package/dist/mfe-shared/navigation.js +1 -1
  29. package/dist/mfe-shared/navigation.js.map +1 -1
  30. package/dist/types/hooks/check-scrolled.d.ts +3 -0
  31. package/dist/types/hooks/debounce.d.ts +1 -0
  32. package/dist/types/hooks/index.d.ts +4 -4
  33. package/dist/types/hooks/use-fetch-data.d.ts +11 -0
  34. package/dist/types/mfe-shared/auth.d.ts +3 -3
  35. package/dist/types/mfe-shared/auth.debug.d.ts +8 -0
  36. package/dist/types/mfe-shared/auth.ssr.d.ts +4 -4
  37. package/dist/types/mfe-shared/cart.d.ts +9 -33
  38. package/dist/types/mfe-shared/cart.types.d.ts +31 -0
  39. package/dist/types/mfe-shared/index.d.ts +11 -8
  40. package/dist/types/mfe-shared/navigation.d.ts +2 -2
  41. package/dist/types/mfe-shared/types.d.ts +3 -3
  42. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- import{objectWithoutProperties as r,slicedToArray as o,objectSpread2 as a}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsx as t,Fragment as n,jsxs as e}from"react/jsx-runtime";import{useState as l,useEffect as i,Fragment as c}from"react";import{useDebounce as u}from"../hooks/index.js";var s=["src","fallbackSrc","alt","loading","debounceDelay"],d=function(d){var f=d.src,m=d.fallbackSrc,p=d.alt,b=d.loading,g=d.debounceDelay,j=void 0===g?0:g,v=r(d,s),S=u(f,j),h=u(m,j),k=j>0?S:f,x=j>0?h:m,y=l(!0),D=o(y,2),L=D[0],P=D[1],_=l(null!=k?k:x),A=o(_,2),B=A[0],E=A[1];i((function(){E(null!=k?k:x),P(!0)}),[k,x]);var F=L&&b?b:t(n,{});return e(c,{children:[F,t("img",a(a({},v),{},{src:B,alt:p,onLoadStart:function(){return P(!0)},onLoad:function(){return P(!1)},onError:function(){E(m),P(!1)}}))]})};export{d as default};
1
+ import{objectWithoutProperties as r,slicedToArray as o,objectSpread2 as a}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsx as t,Fragment as e,jsxs as n}from"react/jsx-runtime";import{useState as l,useEffect as c,Fragment as i}from"react";import{useDebounce as u}from"../hooks/debounce.js";var s=["src","fallbackSrc","alt","loading","debounceDelay"],d=function(d){var f=d.src,m=d.fallbackSrc,p=d.alt,b=d.loading,g=d.debounceDelay,j=void 0===g?0:g,v=r(d,s),S=u(f,j),h=u(m,j),k=j>0?S:f,y=j>0?h:m,x=l(!0),D=o(x,2),L=D[0],P=D[1],_=l(null!=k?k:y),A=o(_,2),B=A[0],E=A[1];c((function(){E(null!=k?k:y),P(!0)}),[k,y]);var F=L&&b?b:t(e,{});return n(i,{children:[F,t("img",a(a({},v),{},{src:B,alt:p,onLoadStart:function(){return P(!0)},onLoad:function(){return P(!1)},onError:function(){E(m),P(!1)}}))]})};export{d as default};
2
2
  //# sourceMappingURL=image-with-fallback.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"image-with-fallback.js","sources":["../../src/components/image-with-fallback.tsx"],"sourcesContent":["import React, { FC, Fragment, ReactNode, useEffect, useState } from 'react'\r\nimport { useDebounce } from '../hooks'\r\n\r\nexport interface IImageWithFallbackPropsOwner {\r\n src?: string\r\n alt?: string\r\n fallbackSrc: string\r\n loading?: ReactNode\r\n debounceDelay?: number\r\n}\r\n\r\nexport type IImageProps = Omit<React.ImgHTMLAttributes<HTMLImageElement>, keyof IImageWithFallbackPropsOwner>\r\n\r\nexport interface IImageWithFallbackProps extends IImageProps, IImageWithFallbackPropsOwner {}\r\n\r\nconst ImageWithFallback: FC<IImageWithFallbackProps> = ({ src, fallbackSrc, alt, loading, debounceDelay = 0, ...props }) => {\r\n const debouncedSrc = useDebounce(src, debounceDelay)\r\n const debouncedFallbackSrc = useDebounce(fallbackSrc, debounceDelay)\r\n\r\n const effectiveSrc = debounceDelay > 0 ? debouncedSrc : src\r\n const effectiveFallbackSrc = debounceDelay > 0 ? debouncedFallbackSrc : fallbackSrc\r\n\r\n const [isLoading, setLoading] = useState(true)\r\n const [imgSrc, setImgSrc] = useState(effectiveSrc ?? effectiveFallbackSrc)\r\n\r\n useEffect(() => {\r\n setImgSrc(effectiveSrc ?? effectiveFallbackSrc)\r\n setLoading(true)\r\n }, [effectiveSrc, effectiveFallbackSrc])\r\n\r\n const loadingElement = isLoading && loading ? loading : <></>\r\n\r\n return (\r\n <Fragment>\r\n {loadingElement}\r\n <img\r\n {...props}\r\n src={imgSrc}\r\n alt={alt}\r\n onLoadStart={() => setLoading(true)}\r\n onLoad={() => setLoading(false)}\r\n onError={() => {\r\n setImgSrc(fallbackSrc)\r\n setLoading(false)\r\n }}\r\n />\r\n </Fragment>\r\n )\r\n}\r\n\r\nexport default ImageWithFallback\r\n"],"names":["ImageWithFallback","_ref","src","fallbackSrc","alt","loading","_ref$debounceDelay","debounceDelay","props","_objectWithoutProperties","_excluded","debouncedSrc","useDebounce","debouncedFallbackSrc","effectiveSrc","effectiveFallbackSrc","_useState","useState","_useState2","_slicedToArray","isLoading","setLoading","_useState3","_useState4","imgSrc","setImgSrc","useEffect","loadingElement","_jsx","_jsxs","Fragment","onLoadStart","onLoad","onError"],"mappings":"mWAeMA,EAAiD,SAAhCC,GAAoG,IAAjEC,EAAGD,EAAHC,IAAKC,EAAWF,EAAXE,YAAaC,EAAGH,EAAHG,IAAKC,EAAOJ,EAAPI,QAAOC,EAAAL,EAAEM,cAAAA,OAAgB,IAAHD,EAAG,EAACA,EAAKE,EAAKC,EAAAR,EAAAS,GAC7GC,EAAeC,EAAYV,EAAKK,GAChCM,EAAuBD,EAAYT,EAAaI,GAEhDO,EAAeP,EAAgB,EAAII,EAAeT,EAClDa,EAAuBR,EAAgB,EAAIM,EAAuBV,EAExEa,EAAgCC,GAAS,GAAKC,EAAAC,EAAAH,EAAA,GAAvCI,EAASF,EAAA,GAAEG,EAAUH,EAAA,GAC5BI,EAA4BL,EAASH,QAAAA,EAAgBC,GAAqBQ,EAAAJ,EAAAG,EAAA,GAAnEE,EAAMD,EAAA,GAAEE,EAASF,EAAA,GAExBG,GAAU,WACRD,EAAUX,QAAAA,EAAgBC,GAC1BM,GAAW,EACb,GAAG,CAACP,EAAcC,IAElB,IAAMY,EAAiBP,GAAaf,EAAUA,EAAUuB,QAExD,OACEC,EAACC,aACEH,EACDC,eACMpB,GAAK,GAAA,CACTN,IAAKsB,EACLpB,IAAKA,EACL2B,YAAa,WAAF,OAAQV,GAAW,EAAK,EACnCW,OAAQ,WAAF,OAAQX,GAAW,EAAM,EAC/BY,QAAS,WACPR,EAAUtB,GACVkB,GAAW,EACb,OAIR"}
1
+ {"version":3,"file":"image-with-fallback.js","sources":["../../src/components/image-with-fallback.tsx"],"sourcesContent":["import React, { FC, Fragment, ReactNode, useEffect, useState } from 'react'\r\nimport { useDebounce } from '../hooks'\r\n\r\nexport interface IImageWithFallbackPropsOwner {\r\n src?: string\r\n alt?: string\r\n fallbackSrc: string\r\n loading?: ReactNode\r\n debounceDelay?: number\r\n}\r\n\r\nexport type IImageProps = Omit<React.ImgHTMLAttributes<HTMLImageElement>, keyof IImageWithFallbackPropsOwner>\r\n\r\nexport interface IImageWithFallbackProps extends IImageProps, IImageWithFallbackPropsOwner {}\r\n\r\nconst ImageWithFallback: FC<IImageWithFallbackProps> = ({ src, fallbackSrc, alt, loading, debounceDelay = 0, ...props }) => {\r\n const debouncedSrc = useDebounce(src, debounceDelay)\r\n const debouncedFallbackSrc = useDebounce(fallbackSrc, debounceDelay)\r\n\r\n const effectiveSrc = debounceDelay > 0 ? debouncedSrc : src\r\n const effectiveFallbackSrc = debounceDelay > 0 ? debouncedFallbackSrc : fallbackSrc\r\n\r\n const [isLoading, setLoading] = useState(true)\r\n const [imgSrc, setImgSrc] = useState(effectiveSrc ?? effectiveFallbackSrc)\r\n\r\n useEffect(() => {\r\n setImgSrc(effectiveSrc ?? effectiveFallbackSrc)\r\n setLoading(true)\r\n }, [effectiveSrc, effectiveFallbackSrc])\r\n\r\n const loadingElement = isLoading && loading ? loading : <></>\r\n\r\n return (\r\n <Fragment>\r\n {loadingElement}\r\n <img\r\n {...props}\r\n src={imgSrc}\r\n alt={alt}\r\n onLoadStart={() => setLoading(true)}\r\n onLoad={() => setLoading(false)}\r\n onError={() => {\r\n setImgSrc(fallbackSrc)\r\n setLoading(false)\r\n }}\r\n />\r\n </Fragment>\r\n )\r\n}\r\n\r\nexport default ImageWithFallback\r\n"],"names":["ImageWithFallback","_ref","src","fallbackSrc","alt","loading","_ref$debounceDelay","debounceDelay","props","_objectWithoutProperties","_excluded","debouncedSrc","useDebounce","debouncedFallbackSrc","effectiveSrc","effectiveFallbackSrc","_useState","useState","_useState2","_slicedToArray","isLoading","setLoading","_useState3","_useState4","imgSrc","setImgSrc","useEffect","loadingElement","_jsx","_jsxs","Fragment","onLoadStart","onLoad","onError"],"mappings":"sWAeMA,EAAiD,SAAhCC,GAAoG,IAAjEC,EAAGD,EAAHC,IAAKC,EAAWF,EAAXE,YAAaC,EAAGH,EAAHG,IAAKC,EAAOJ,EAAPI,QAAOC,EAAAL,EAAEM,cAAAA,OAAgB,IAAHD,EAAG,EAACA,EAAKE,EAAKC,EAAAR,EAAAS,GAC7GC,EAAeC,EAAYV,EAAKK,GAChCM,EAAuBD,EAAYT,EAAaI,GAEhDO,EAAeP,EAAgB,EAAII,EAAeT,EAClDa,EAAuBR,EAAgB,EAAIM,EAAuBV,EAExEa,EAAgCC,GAAS,GAAKC,EAAAC,EAAAH,EAAA,GAAvCI,EAASF,EAAA,GAAEG,EAAUH,EAAA,GAC5BI,EAA4BL,EAASH,QAAAA,EAAgBC,GAAqBQ,EAAAJ,EAAAG,EAAA,GAAnEE,EAAMD,EAAA,GAAEE,EAASF,EAAA,GAExBG,GAAU,WACRD,EAAUX,QAAAA,EAAgBC,GAC1BM,GAAW,EACb,GAAG,CAACP,EAAcC,IAElB,IAAMY,EAAiBP,GAAaf,EAAUA,EAAUuB,QAExD,OACEC,EAACC,aACEH,EACDC,eACMpB,GAAK,GAAA,CACTN,IAAKsB,EACLpB,IAAKA,EACL2B,YAAa,WAAF,OAAQV,GAAW,EAAK,EACnCW,OAAQ,WAAF,OAAQX,GAAW,EAAM,EAC/BY,QAAS,WACPR,EAAUtB,GACVkB,GAAW,EACb,OAIR"}
@@ -0,0 +1,2 @@
1
+ import{slicedToArray as r}from"../_virtual/_rollupPluginBabelHelpers.js";import{useState as n,useEffect as o}from"react";var e=function(){var e=n(!1),i=r(e,2),l=i[0],t=i[1];return o((function(){var r=function(){var r=window.scrollY>0;r!==l&&t(r)};return window.addEventListener("scroll",r),function(){return window.removeEventListener("scroll",r)}}),[l]),o((function(){var r=window.scrollY>0;r!==l&&t(r)}),[]),{isScrolled:l}};export{e as useCheckScrolled};
2
+ //# sourceMappingURL=check-scrolled.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-scrolled.js","sources":["../../src/hooks/check-scrolled.ts"],"sourcesContent":["/* eslint-disable react-hooks/exhaustive-deps*/\r\nimport { useEffect, useState } from 'react'\r\n\r\nexport const useCheckScrolled = () => {\r\n const [isScrolled, setIsScrolled] = useState(false)\r\n\r\n useEffect(() => {\r\n const handleScroll = () => {\r\n const scrolled = window.scrollY > 0\r\n if (scrolled !== isScrolled) setIsScrolled(scrolled)\r\n }\r\n\r\n window.addEventListener('scroll', handleScroll)\r\n return () => window.removeEventListener('scroll', handleScroll)\r\n }, [isScrolled])\r\n\r\n useEffect(() => {\r\n const scrolled = window.scrollY > 0\r\n if (scrolled !== isScrolled) setIsScrolled(scrolled)\r\n }, [])\r\n\r\n return { isScrolled }\r\n}\r\n"],"names":["useCheckScrolled","_useState","useState","_useState2","_slicedToArray","isScrolled","setIsScrolled","useEffect","handleScroll","scrolled","window","scrollY","addEventListener","removeEventListener"],"mappings":"6HAGaA,EAAmB,WAC9B,IAAAC,EAAoCC,GAAS,GAAMC,EAAAC,EAAAH,EAAA,GAA5CI,EAAUF,EAAA,GAAEG,EAAaH,EAAA,GAiBhC,OAfAI,GAAU,WACR,IAAMC,EAAe,WACnB,IAAMC,EAAWC,OAAOC,QAAU,EAC9BF,IAAaJ,GAAYC,EAAcG,EAC5C,EAGD,OADAC,OAAOE,iBAAiB,SAAUJ,GAC3B,WAAA,OAAME,OAAOG,oBAAoB,SAAUL,EAAa,CACjE,GAAG,CAACH,IAEJE,GAAU,WACR,IAAME,EAAWC,OAAOC,QAAU,EAC9BF,IAAaJ,GAAYC,EAAcG,EAC5C,GAAE,IAEI,CAAEJ,WAAAA,EACX"}
@@ -0,0 +1,2 @@
1
+ import{slicedToArray as r}from"../_virtual/_rollupPluginBabelHelpers.js";import{useState as t,useEffect as o}from"react";var e=function(e,i){var n=t(e),u=r(n,2),a=u[0],l=u[1];return o((function(){if(!(i<=0)){var r=setTimeout((function(){l(e)}),i);return function(){clearTimeout(r)}}l(e)}),[e,i]),a};export{e as useDebounce};
2
+ //# sourceMappingURL=debounce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debounce.js","sources":["../../src/hooks/debounce.ts"],"sourcesContent":["/* eslint-disable react-hooks/exhaustive-deps*/\r\nimport { useEffect, useState } from 'react'\r\n\r\nexport const useDebounce = <T>(value: T, delay: number): T => {\r\n const [debouncedValue, setDebouncedValue] = useState<T>(value)\r\n\r\n useEffect(() => {\r\n if (delay <= 0) {\r\n setDebouncedValue(value)\r\n return\r\n }\r\n\r\n const handler = setTimeout(() => {\r\n setDebouncedValue(value)\r\n }, delay)\r\n\r\n return () => {\r\n clearTimeout(handler)\r\n }\r\n }, [value, delay])\r\n\r\n return debouncedValue\r\n}\r\n"],"names":["useDebounce","value","delay","_useState","useState","_useState2","_slicedToArray","debouncedValue","setDebouncedValue","useEffect","handler","setTimeout","clearTimeout"],"mappings":"yHAGO,IAAMA,EAAc,SAAIC,EAAUC,GACvC,IAAAC,EAA4CC,EAAYH,GAAMI,EAAAC,EAAAH,EAAA,GAAvDI,EAAcF,EAAA,GAAEG,EAAiBH,EAAA,GAiBxC,OAfAI,GAAU,WACR,KAAIP,GAAS,GAAb,CAKA,IAAMQ,EAAUC,YAAW,WACzBH,EAAkBP,EACnB,GAAEC,GAEH,OAAO,WACLU,aAAaF,EACd,CARA,CAFCF,EAAkBP,EAWtB,GAAG,CAACA,EAAOC,IAEJK,CACT"}
@@ -1,2 +1,2 @@
1
- import{slicedToArray as r}from"../_virtual/_rollupPluginBabelHelpers.js";import{useState as n,useEffect as o}from"react";var t=function(){var t=n(!1),e=r(t,2),i=e[0],u=e[1];return o((function(){var r=function(){var r=window.scrollY>0;r!==i&&u(r)};return window.addEventListener("scroll",r),function(){return window.removeEventListener("scroll",r)}}),[i]),o((function(){var r=window.scrollY>0;r!==i&&u(r)}),[]),{isScrolled:i}},e=function(t,e){var i=n(t),u=r(i,2),l=u[0],c=u[1];return o((function(){if(!(e<=0)){var r=setTimeout((function(){c(t)}),e);return function(){clearTimeout(r)}}c(t)}),[t,e]),l};export{t as useCheckScrolled,e as useDebounce};
1
+ export{useCheckScrolled}from"./check-scrolled.js";export{useDebounce}from"./debounce.js";export{errorMessageHandler,useFetchData}from"./use-fetch-data.js";
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/hooks/index.ts"],"sourcesContent":["/* eslint-disable react-hooks/exhaustive-deps*/\r\nimport { useEffect, useState } from 'react'\r\n\r\nexport const useCheckScrolled = () => {\r\n const [isScrolled, setIsScrolled] = useState(false)\r\n\r\n useEffect(() => {\r\n const handleScroll = () => {\r\n const scrolled = window.scrollY > 0\r\n if (scrolled !== isScrolled) setIsScrolled(scrolled)\r\n }\r\n\r\n window.addEventListener('scroll', handleScroll)\r\n return () => window.removeEventListener('scroll', handleScroll)\r\n }, [isScrolled])\r\n\r\n useEffect(() => {\r\n const scrolled = window.scrollY > 0\r\n if (scrolled !== isScrolled) setIsScrolled(scrolled)\r\n }, [])\r\n\r\n return { isScrolled }\r\n}\r\n\r\nexport const useDebounce = <T>(value: T, delay: number): T => {\r\n const [debouncedValue, setDebouncedValue] = useState<T>(value)\r\n\r\n useEffect(() => {\r\n if (delay <= 0) {\r\n setDebouncedValue(value)\r\n return\r\n }\r\n\r\n const handler = setTimeout(() => {\r\n setDebouncedValue(value)\r\n }, delay)\r\n\r\n return () => {\r\n clearTimeout(handler)\r\n }\r\n }, [value, delay])\r\n\r\n return debouncedValue\r\n}\r\n"],"names":["useCheckScrolled","_useState","useState","_useState2","_slicedToArray","isScrolled","setIsScrolled","useEffect","handleScroll","scrolled","window","scrollY","addEventListener","removeEventListener","useDebounce","value","delay","_useState3","_useState4","debouncedValue","setDebouncedValue","handler","setTimeout","clearTimeout"],"mappings":"6HAGaA,EAAmB,WAC9B,IAAAC,EAAoCC,GAAS,GAAMC,EAAAC,EAAAH,EAAA,GAA5CI,EAAUF,EAAA,GAAEG,EAAaH,EAAA,GAiBhC,OAfAI,GAAU,WACR,IAAMC,EAAe,WACnB,IAAMC,EAAWC,OAAOC,QAAU,EAC9BF,IAAaJ,GAAYC,EAAcG,EAC5C,EAGD,OADAC,OAAOE,iBAAiB,SAAUJ,GAC3B,WAAA,OAAME,OAAOG,oBAAoB,SAAUL,EAAa,CACjE,GAAG,CAACH,IAEJE,GAAU,WACR,IAAME,EAAWC,OAAOC,QAAU,EAC9BF,IAAaJ,GAAYC,EAAcG,EAC5C,GAAE,IAEI,CAAEJ,WAAAA,EACX,EAEaS,EAAc,SAAIC,EAAUC,GACvC,IAAAC,EAA4Cf,EAAYa,GAAMG,EAAAd,EAAAa,EAAA,GAAvDE,EAAcD,EAAA,GAAEE,EAAiBF,EAAA,GAiBxC,OAfAX,GAAU,WACR,KAAIS,GAAS,GAAb,CAKA,IAAMK,EAAUC,YAAW,WACzBF,EAAkBL,EACnB,GAAEC,GAEH,OAAO,WACLO,aAAaF,EACd,CARA,CAFCD,EAAkBL,EAWtB,GAAG,CAACA,EAAOC,IAEJG,CACT"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ import{slicedToArray as r,asyncToGenerator as n,regenerator as o}from"../_virtual/_rollupPluginBabelHelpers.js";import{useState as t,useRef as e,useCallback as a,useEffect as l}from"react";var u=function(r,n){var o,t=r instanceof Error&&("AbortError"===r.name||"CanceledError"===r.name);return(!t||null!=n&&n.logAll)&&console.log(null!==(o=null==n?void 0:n.message)&&void 0!==o?o:"Error fetching data:",r),{isAbortError:t}};function c(c){var i=t(),s=r(i,2),v=s[0],f=s[1],d=t(!0),b=r(d,2),g=b[0],p=b[1],m=e(null),A=a(function(){var r=n(o().m((function r(n){var t,e,a;return o().w((function(r){for(;;)switch(r.n){case 0:return r.p=0,p(!0),r.n=1,c(n);case 1:t=r.v,f(t),p(!1),r.n=3;break;case 2:r.p=2,a=r.v,e=u(a),e.isAbortError||p(!1);case 3:return r.a(2)}}),r,null,[[0,2]])})));return function(n){return r.apply(this,arguments)}}(),[c]);return l((function(){var r;m.current&&!m.current.signal.aborted&&(null===(r=m.current)||void 0===r||r.abort());return m.current=new AbortController,A(m.current.signal),function(){var r;null===(r=m.current)||void 0===r||r.abort()}}),[]),{data:v,loading:g}}export{u as errorMessageHandler,c as useFetchData};
2
+ //# sourceMappingURL=use-fetch-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-fetch-data.js","sources":["../../src/hooks/use-fetch-data.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any*/\r\nimport { useCallback, useEffect, useRef, useState } from 'react'\r\n\r\nexport const errorMessageHandler = (error: any, options?: { message?: string; logAll?: boolean }) => {\r\n const isAbortError = error instanceof Error && (error.name === 'AbortError' || error.name === 'CanceledError')\r\n if (!isAbortError || options?.logAll) console.log(options?.message ?? 'Error fetching data:', error)\r\n return { isAbortError }\r\n}\r\n\r\nexport type FetcherFunction<T> = (signal?: AbortSignal) => Promise<T>\r\n\r\nexport function useFetchData<T, F extends FetcherFunction<T>>(fetcher: F) {\r\n type DataType = Awaited<ReturnType<F>>\r\n const [data, setData] = useState<DataType>()\r\n const [loading, setLoading] = useState<boolean>(true)\r\n const abortController = useRef<AbortController | null>(null)\r\n\r\n const fetchTableData = useCallback(\r\n async (signal?: AbortSignal) => {\r\n try {\r\n setLoading(true)\r\n const res = await fetcher(signal)\r\n setData(res as DataType)\r\n setLoading(false)\r\n } catch (error) {\r\n const { isAbortError } = errorMessageHandler(error)\r\n if (!isAbortError) setLoading(false)\r\n }\r\n },\r\n [fetcher]\r\n )\r\n\r\n useEffect(() => {\r\n if (abortController.current && !abortController.current.signal.aborted) {\r\n abortController.current?.abort()\r\n }\r\n\r\n abortController.current = new AbortController()\r\n fetchTableData(abortController.current.signal)\r\n return () => {\r\n abortController.current?.abort()\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n return { data, loading }\r\n}\r\n"],"names":["errorMessageHandler","error","options","_options$message","isAbortError","Error","name","logAll","console","log","message","useFetchData","fetcher","_useState","useState","_useState2","_slicedToArray","data","setData","_useState3","_useState4","loading","setLoading","abortController","useRef","fetchTableData","useCallback","_ref","_asyncToGenerator","_regenerator","m","_callee","signal","res","_errorMessageHandler","_t","w","_context","n","p","v","a","_x","apply","this","arguments","useEffect","_abortController$curr","current","aborted","abort","AbortController","_abortController$curr2"],"mappings":"6LAGO,IAAMA,EAAsB,SAACC,EAAYC,GAAoD,IAAAC,EAC5FC,EAAeH,aAAiBI,QAAyB,eAAfJ,EAAMK,MAAwC,kBAAfL,EAAMK,MAErF,QADKF,GAAgBF,SAAAA,EAASK,SAAQC,QAAQC,IAAoB,QAAjBN,EAACD,aAAAA,EAAAA,EAASQ,eAAO,IAAAP,EAAAA,EAAI,uBAAwBF,GACvF,CAAEG,aAAAA,EACX,EAIM,SAAUO,EAA8CC,GAE5D,IAAAC,EAAwBC,IAAoBC,EAAAC,EAAAH,EAAA,GAArCI,EAAIF,EAAA,GAAEG,EAAOH,EAAA,GACpBI,EAA8BL,GAAkB,GAAKM,EAAAJ,EAAAG,EAAA,GAA9CE,EAAOD,EAAA,GAAEE,EAAUF,EAAA,GACpBG,EAAkBC,EAA+B,MAEjDC,EAAiBC,EAAW,WAAA,IAAAC,EAAAC,EAAAC,IAAAC,GAChC,SAAAC,EAAOC,GAAoB,IAAAC,EAAAC,EAAAC,EAAA,OAAAN,IAAAO,GAAA,SAAAC,GAAA,cAAAA,EAAAC,GAAA,KAAA,EAEP,OAFOD,EAAAE,EAAA,EAEvBjB,GAAW,GAAKe,EAAAC,EAAA,EACE1B,EAAQoB,GAAO,KAAA,EAA3BC,EAAGI,EAAAG,EACTtB,EAAQe,GACRX,GAAW,GAAMe,EAAAC,EAAA,EAAA,MAAA,KAAA,EAAAD,EAAAE,EAAA,EAAAJ,EAAAE,EAAAG,EAAAN,EAEQlC,EAAmBmC,GAAxBD,EAAZ9B,cACWkB,GAAW,GAAM,KAAA,EAAA,OAAAe,EAAAI,EAAA,GAAA,GAAAV,EAAA,KAAA,CAAA,CAAA,EAAA,SAEvC,OAAA,SAAAW,GAAA,OAAAf,EAAAgB,MAAAC,KAAAC,UAAA,EAX+B,GAYhC,CAACjC,IAgBH,OAbAkC,GAAU,WACgE,IAAAC,EAApExB,EAAgByB,UAAYzB,EAAgByB,QAAQhB,OAAOiB,UACtC,QAAvBF,EAAAxB,EAAgByB,eAAO,IAAAD,GAAvBA,EAAyBG,SAK3B,OAFA3B,EAAgByB,QAAU,IAAIG,gBAC9B1B,EAAeF,EAAgByB,QAAQhB,QAChC,WAAK,IAAAoB,EACa,QAAvBA,EAAA7B,EAAgByB,eAAO,IAAAI,GAAvBA,EAAyBF,OAC1B,CAEF,GAAE,IAEI,CAAEjC,KAAAA,EAAMI,QAAAA,EACjB"}
@@ -0,0 +1,2 @@
1
+ import{slicedToArray as t,objectSpread2 as e,toConsumableArray as r,defineProperty as o}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsxs as i,jsx as n}from"react/jsx-runtime";import{useState as a,useEffect as l}from"react";import{AUTH_CHANNELS as c}from"./auth.types.js";var d=function(d){var s=a({}),p=t(s,2),f=p[0],m=p[1],u=d.channelPrefix||"mfe:auth:";l((function(){var t=Object.values(c),i=function(i){var n=i,a=n.type;if(t.includes(a)){var l=Date.now(),c=n.detail;m((function(t){var i=t[a]||{channel:a,history:[]},n=[{channel:a,payload:c,timestamp:l}].concat(r(i.history.slice(0,9)));return e(e({},t),{},o({},a,e(e({},i),{},{history:n})))}))}};return t.forEach((function(t){window.addEventListener(t,i)})),function(){t.forEach((function(t){window.removeEventListener(t,i)}))}}),[u]);var h=e({position:"fixed",top:"10px",right:"10px",background:"rgba(0, 0, 0, 0.9)",color:"#fff",padding:"12px",borderRadius:"8px",fontSize:"12px",fontFamily:"monospace",zIndex:9999,maxWidth:"400px",maxHeight:"500px",overflow:"auto",border:"2px solid #4CAF50"},d.style);return i("div",{style:h,children:[n("h4",{style:{margin:"0 0 10px 0",color:"#4CAF50"},children:d.title||"MFE Auth Debug Panel"}),0===Object.keys(f).length?n("div",{style:{color:"#888"},children:"No auth events yet..."}):Object.entries(f).map((function(e){var r=t(e,2),o=r[0],a=r[1];return i("div",{style:{marginBottom:"15px"},children:[n("div",{style:{fontWeight:"bold",color:"#FFD700",marginBottom:"5px"},children:o.replace(u,"")}),a.history.map((function(t,e){return i("div",{style:{marginBottom:"5px",paddingLeft:"10px",borderLeft:"2px solid #555",fontSize:"11px"},children:[n("div",{style:{color:"#888"},children:new Date(t.timestamp).toLocaleTimeString()}),n("div",{style:{color:"#fff"},children:JSON.stringify(t.payload,null,2)})]},"".concat(t.timestamp,"-").concat(e))}))]},o)}))]})};export{d as MfeAuthDebugPanel};
2
+ //# sourceMappingURL=auth.debug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.debug.js","sources":["../../src/mfe-shared/auth.debug.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react'\r\nimport { AUTH_CHANNELS } from './auth.types'\r\n\r\ninterface IEventHistoryEntry {\r\n channel: string\r\n payload: any\r\n timestamp: number\r\n}\r\n\r\ninterface IEventDebugData {\r\n channel: string\r\n history: IEventHistoryEntry[]\r\n}\r\n\r\ninterface IDebugPanelProps {\r\n title?: string\r\n style?: React.CSSProperties\r\n channelPrefix?: string\r\n}\r\n\r\nexport const MfeAuthDebugPanel: React.FC<IDebugPanelProps> = (props) => {\r\n const [events, setEvents] = useState<Record<string, IEventDebugData>>({})\r\n const channelPrefix = props.channelPrefix || 'mfe:auth:'\r\n\r\n useEffect(() => {\r\n const authChannels = Object.values(AUTH_CHANNELS)\r\n\r\n const handleEvent = (e: Event) => {\r\n const customEvent = e as CustomEvent\r\n const channel = customEvent.type\r\n\r\n if (!authChannels.includes(channel)) return\r\n\r\n const timestamp = Date.now()\r\n const payload = customEvent.detail\r\n\r\n setEvents((prev) => {\r\n const existing = prev[channel] || { channel, history: [] }\r\n const newHistory = [\r\n { channel, payload, timestamp },\r\n ...existing.history.slice(0, 9) // Keep last 10 events\r\n ]\r\n\r\n return {\r\n ...prev,\r\n [channel]: {\r\n ...existing,\r\n history: newHistory\r\n }\r\n }\r\n })\r\n }\r\n\r\n // Listen to all auth channels\r\n authChannels.forEach((channel) => {\r\n window.addEventListener(channel, handleEvent)\r\n })\r\n\r\n return () => {\r\n authChannels.forEach((channel) => {\r\n window.removeEventListener(channel, handleEvent)\r\n })\r\n }\r\n }, [channelPrefix])\r\n\r\n const panelStyle: React.CSSProperties = {\r\n position: 'fixed',\r\n top: '10px',\r\n right: '10px',\r\n background: 'rgba(0, 0, 0, 0.9)',\r\n color: '#fff',\r\n padding: '12px',\r\n borderRadius: '8px',\r\n fontSize: '12px',\r\n fontFamily: 'monospace',\r\n zIndex: 9999,\r\n maxWidth: '400px',\r\n maxHeight: '500px',\r\n overflow: 'auto',\r\n border: '2px solid #4CAF50',\r\n ...props.style\r\n }\r\n\r\n return (\r\n <div style={panelStyle}>\r\n <h4 style={{ margin: '0 0 10px 0', color: '#4CAF50' }}>\r\n {props.title || 'MFE Auth Debug Panel'}\r\n </h4>\r\n \r\n {Object.keys(events).length === 0 ? (\r\n <div style={{ color: '#888' }}>No auth events yet...</div>\r\n ) : (\r\n Object.entries(events).map(([channel, data]) => (\r\n <div key={channel} style={{ marginBottom: '15px' }}>\r\n <div style={{ fontWeight: 'bold', color: '#FFD700', marginBottom: '5px' }}>\r\n {channel.replace(channelPrefix, '')}\r\n </div>\r\n \r\n {data.history.map((event, index) => (\r\n <div\r\n key={`${event.timestamp}-${index}`}\r\n style={{\r\n marginBottom: '5px',\r\n paddingLeft: '10px',\r\n borderLeft: '2px solid #555',\r\n fontSize: '11px'\r\n }}\r\n >\r\n <div style={{ color: '#888' }}>\r\n {new Date(event.timestamp).toLocaleTimeString()}\r\n </div>\r\n <div style={{ color: '#fff' }}>\r\n {JSON.stringify(event.payload, null, 2)}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n ))\r\n )}\r\n </div>\r\n )\r\n}\r\n"],"names":["MfeAuthDebugPanel","props","_useState","useState","_useState2","_slicedToArray","events","setEvents","channelPrefix","useEffect","authChannels","Object","values","AUTH_CHANNELS","handleEvent","e","customEvent","channel","type","includes","timestamp","Date","now","payload","detail","prev","existing","history","newHistory","concat","_toConsumableArray","slice","_objectSpread","_defineProperty","forEach","window","addEventListener","removeEventListener","panelStyle","position","top","right","background","color","padding","borderRadius","fontSize","fontFamily","zIndex","maxWidth","maxHeight","overflow","border","style","_jsxs","children","_jsx","margin","title","keys","length","entries","map","_ref","_ref2","data","marginBottom","fontWeight","replace","event","index","paddingLeft","borderLeft","toLocaleTimeString","JSON","stringify"],"mappings":"6RAoBaA,EAAgD,SAACC,GAC5D,IAAAC,EAA4BC,EAA0C,IAAGC,EAAAC,EAAAH,EAAA,GAAlEI,EAAMF,EAAA,GAAEG,EAASH,EAAA,GAClBI,EAAgBP,EAAMO,eAAiB,YAE7CC,GAAU,WACR,IAAMC,EAAeC,OAAOC,OAAOC,GAE7BC,EAAc,SAACC,GACnB,IAAMC,EAAcD,EACdE,EAAUD,EAAYE,KAE5B,GAAKR,EAAaS,SAASF,GAA3B,CAEA,IAAMG,EAAYC,KAAKC,MACjBC,EAAUP,EAAYQ,OAE5BjB,GAAU,SAACkB,GACT,IAAMC,EAAWD,EAAKR,IAAY,CAAEA,QAAAA,EAASU,QAAS,IAChDC,EACJ,CAAA,CAAEX,QAAAA,EAASM,QAAAA,EAASH,UAAAA,IAAWS,OAAAC,EAC5BJ,EAASC,QAAQI,MAAM,EAAG,KAG/B,OAAAC,EAAAA,EAAA,CAAA,EACKP,GAAIQ,CAAAA,EAAAA,EACNhB,CAAAA,EAAAA,EAAOe,EAAAA,KACHN,GAAQ,CAAA,EAAA,CACXC,QAASC,KAGf,GAnBqC,CAoBtC,EAOD,OAJAlB,EAAawB,SAAQ,SAACjB,GACpBkB,OAAOC,iBAAiBnB,EAASH,EACnC,IAEO,WACLJ,EAAawB,SAAQ,SAACjB,GACpBkB,OAAOE,oBAAoBpB,EAASH,EACtC,GACD,CACH,GAAG,CAACN,IAEJ,IAAM8B,EAAUN,EAAA,CACdO,SAAU,QACVC,IAAK,OACLC,MAAO,OACPC,WAAY,qBACZC,MAAO,OACPC,QAAS,OACTC,aAAc,MACdC,SAAU,OACVC,WAAY,YACZC,OAAQ,KACRC,SAAU,QACVC,UAAW,QACXC,SAAU,OACVC,OAAQ,qBACLnD,EAAMoD,OAGX,OACEC,EAAA,MAAA,CAAKD,MAAOf,EAAUiB,SAAA,CACpBC,EAAI,KAAA,CAAAH,MAAO,CAAEI,OAAQ,aAAcd,MAAO,WACvCY,SAAAtD,EAAMyD,OAAS,yBAGc,IAA/B/C,OAAOgD,KAAKrD,GAAQsD,OACnBJ,EAAK,MAAA,CAAAH,MAAO,CAAEV,MAAO,QAAqCY,SAAA,0BAE1D5C,OAAOkD,QAAQvD,GAAQwD,KAAI,SAAAC,GAAA,IAAAC,EAAA3D,EAAA0D,EAAA,GAAE9C,EAAO+C,EAAA,GAAEC,EAAID,EAAA,GAAA,OACxCV,EAAA,MAAA,CAAmBD,MAAO,CAAEa,aAAc,QAAQX,SAAA,CAChDC,EAAK,MAAA,CAAAH,MAAO,CAAEc,WAAY,OAAQxB,MAAO,UAAWuB,aAAc,OAC/DX,SAAAtC,EAAQmD,QAAQ5D,EAAe,MAGjCyD,EAAKtC,QAAQmC,KAAI,SAACO,EAAOC,GAAK,OAC7BhB,EAAA,MAAA,CAEED,MAAO,CACLa,aAAc,MACdK,YAAa,OACbC,WAAY,iBACZ1B,SAAU,QACXS,SAAA,CAEDC,EAAK,MAAA,CAAAH,MAAO,CAAEV,MAAO,QAClBY,SAAA,IAAIlC,KAAKgD,EAAMjD,WAAWqD,uBAE7BjB,EAAA,MAAA,CAAKH,MAAO,CAAEV,MAAO,QAClBY,SAAAmB,KAAKC,UAAUN,EAAM9C,QAAS,KAAM,OAZlC,GAAAM,OAAGwC,EAAMjD,UAAS,KAAAS,OAAIyC,GAcvB,MArBArD,EAuBJ,MAKhB"}
@@ -1,2 +1,2 @@
1
- import{slicedToArray as r,asyncToGenerator as n,objectSpread2 as e,regenerator as i}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsx as o,Fragment as a}from"react/jsx-runtime";import{useState as t,useEffect as u}from"react";import{mfeBridge as s}from"./mfe-bridge.js";import{INITIAL_AUTH_STATE as l,AUTH_CHANNELS as c}from"./auth.types.js";import{isBrowser as d}from"./environment.js";var f=function(f){var p=f.children,h=f.onLogin,v=f.onLogout,b=f.initialState,m=void 0===b?l:b,g=f.authData,A=f.onAuthChange,E=t(m),T=r(E,2),L=T[0],w=T[1];u((function(){if(g){var r=null;(g.id||g.displayName)&&(r={id:g.id||"unknown",displayName:g.displayName||"Unknown User",email:g.email||"",roles:g.roles||[],avatar:g.avatar});var n={isAuthenticated:!!g.id||!!g.displayName,isLoading:!1,user:r,error:null,serverRendered:!d()};w(n),s.publish(c.STATE_CHANGE,n)}}),[g]),u((function(){if(A)return A((function(r){w(r),s.publish(c.STATE_CHANGE,r)}))}),[A]),u((function(){var r=s.subscribe(c.REQUEST_STATE,(function(){s.publish(c.STATE_CHANGE,L)})),n=s.subscribe(c.LOGIN,(function(r){N(r.username,r.password)})),e=s.subscribe(c.LOGOUT,(function(){S()}));return function(){r(),n(),e()}}),[L]);var N=function(){var r=n(i().m((function r(n,o){var a,t,u,l,f;return i().w((function(r){for(;;)switch(r.n){case 0:if(w((function(r){return e(e({},r),{},{isLoading:!0,error:null})})),r.p=1,!h){r.n=3;break}return r.n=2,h({username:n,password:o});case 2:(a=r.v)?(t={isAuthenticated:a.isAuthenticated,isLoading:!1,user:a.user||null,error:a.error||null,serverRendered:!d()},w(t),s.publish(c.STATE_CHANGE,t)):w((function(r){return e(e({},r),{},{isLoading:!1})})),r.n=4;break;case 3:throw new Error("No login handler provided. Please provide an onLogin handler to AuthProvider.");case 4:r.n=6;break;case 5:r.p=5,f=r.v,u=f instanceof Error?f.message:"Login failed",l={isAuthenticated:!1,isLoading:!1,user:null,error:u,serverRendered:!d()},w(l),s.publish(c.STATE_CHANGE,l);case 6:return r.a(2)}}),r,null,[[1,5]])})));return function(n,e){return r.apply(this,arguments)}}(),S=function(){var r=n(i().m((function r(){var n,o,a;return i().w((function(r){for(;;)switch(r.n){case 0:if(w((function(r){return e(e({},r),{},{isLoading:!0})})),r.p=1,!v){r.n=5;break}return r.n=2,v();case 2:if(!1===r.v){r.n=3;break}n={isAuthenticated:!1,isLoading:!1,user:null,error:null,serverRendered:!d()},w(n),s.publish(c.STATE_CHANGE,n),r.n=4;break;case 3:throw new Error("Logout failed");case 4:r.n=6;break;case 5:throw new Error("No logout handler provided. Please provide an onLogout handler to AuthProvider.");case 6:r.n=8;break;case 7:r.p=7,a=r.v,o=a instanceof Error?a.message:"Logout failed",w((function(r){return e(e({},r),{},{isLoading:!1,error:o})}));case 8:return r.a(2)}}),r,null,[[1,7]])})));return function(){return r.apply(this,arguments)}}();return o(a,{children:p})};function p(){var n=t(l),i=r(n,2),o=i[0],a=i[1];u((function(){var r=s.subscribe(c.STATE_CHANGE,(function(r){a(r)}));return s.publish(c.REQUEST_STATE,null),r}),[]);return e(e({},o),{},{login:function(r,n){s.publish(c.LOGIN,{username:r,password:n})},logout:function(){s.publish(c.LOGOUT,null)}})}export{f as AuthProvider,p as useAuth};
1
+ import{slicedToArray as r,asyncToGenerator as n,objectSpread2 as e,regenerator as i}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsx as o,Fragment as a}from"react/jsx-runtime";import{useState as t,useEffect as u}from"react";import{mfeBridge as s}from"./mfe-bridge.js";import{INITIAL_AUTH_STATE as l,AUTH_CHANNELS as c}from"./auth.types.js";import{isBrowser as d}from"./environment.js";var f=function(f){var p=f.children,h=f.onLogin,v=f.onLogout,b=f.initialState,m=void 0===b?l:b,g=f.authData,A=f.onAuthChange,E=t(m),T=r(E,2),L=T[0],w=T[1];u((function(){if(g){var r=null;(g.id||g.displayName)&&(r={id:g.id||"unknown",displayName:g.displayName||"Unknown User",email:g.email||"",roles:g.roles||[],avatar:g.avatar});var n={isAuthenticated:!!g.id||!!g.displayName,isLoading:!1,user:r,error:null,serverRendered:!d()};w(n),s.publish(c.STATE_CHANGE,n)}}),[g]),u((function(){if(A)return A((function(r){w(r),s.publish(c.STATE_CHANGE,r)}))}),[A]),u((function(){var r=s.subscribe(c.REQUEST_STATE,(function(){s.publish(c.STATE_CHANGE,L)})),n=s.subscribe(c.LOGIN,(function(r){N(r.username,r.password)})),e=s.subscribe(c.LOGOUT,(function(){S()}));return function(){r(),n(),e()}}),[L]);var N=function(){var r=n(i().m((function r(n,o){var a,t,u,l,f;return i().w((function(r){for(;;)switch(r.n){case 0:if(w((function(r){return e(e({},r),{},{isLoading:!0,error:null})})),r.p=1,!h){r.n=3;break}return r.n=2,h({username:n,password:o});case 2:(a=r.v)?(t={isAuthenticated:a.isAuthenticated,isLoading:!1,user:a.user||null,error:a.error||null,serverRendered:!d()},w(t),s.publish(c.STATE_CHANGE,t)):w((function(r){return e(e({},r),{},{isLoading:!1})})),r.n=4;break;case 3:throw new Error("No login handler provided. Please provide an onLogin handler to AuthProvider.");case 4:r.n=6;break;case 5:r.p=5,f=r.v,u=f instanceof Error?f.message:"Login failed",l={isAuthenticated:!1,isLoading:!1,user:null,error:u,serverRendered:!d()},w(l),s.publish(c.STATE_CHANGE,l);case 6:return r.a(2)}}),r,null,[[1,5]])})));return function(n,e){return r.apply(this,arguments)}}(),S=function(){var r=n(i().m((function r(){var n,o,a;return i().w((function(r){for(;;)switch(r.n){case 0:if(w((function(r){return e(e({},r),{},{isLoading:!0})})),r.p=1,!v){r.n=5;break}return r.n=2,v();case 2:if(!1===r.v){r.n=3;break}n={isAuthenticated:!1,isLoading:!1,user:null,error:null,serverRendered:!d()},w(n),s.publish(c.STATE_CHANGE,n),r.n=4;break;case 3:throw new Error("Logout failed");case 4:r.n=6;break;case 5:throw new Error("No logout handler provided. Please provide an onLogout handler to AuthProvider.");case 6:r.n=8;break;case 7:r.p=7,a=r.v,o=a instanceof Error?a.message:"Logout failed",w((function(r){return e(e({},r),{},{isLoading:!1,error:o})}));case 8:return r.a(2)}}),r,null,[[1,7]])})));return function(){return r.apply(this,arguments)}}();return o(a,{children:p})};function p(){var n=t(l),i=r(n,2),o=i[0],a=i[1];u((function(){var r=s.subscribe(c.STATE_CHANGE,(function(r){a(r)}));return s.publish(c.REQUEST_STATE,null),r}),[]);return e(e({},o),{},{login:function(r,n){s.publish(c.LOGIN,{username:r,password:n})},logout:function(){s.publish(c.LOGOUT,null)}})}export{f as MfeAuthProvider,p as useMfeAuth};
2
2
  //# sourceMappingURL=auth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sources":["../../src/mfe-shared/auth.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react'\r\nimport { mfeBridge } from './mfe-bridge'\r\nimport { AUTH_CHANNELS, IAuthState, INITIAL_AUTH_STATE, IUser } from './auth.types'\r\nimport { isBrowser } from './environment'\r\n\r\n/**\r\n * Login parameters structure\r\n */\r\nexport interface ILoginParams {\r\n username: string\r\n password: string\r\n}\r\n\r\n/**\r\n * Login response structure\r\n */\r\nexport interface ILoginResponse {\r\n isAuthenticated: boolean\r\n user?: IUser\r\n error?: string\r\n}\r\n\r\nexport interface IAuthProviderProps {\r\n children?: React.ReactNode\r\n\r\n // Custom handlers for manual authentication\r\n // onLogin can simply trigger authentication (like opening a login modal) without returning immediate data\r\n onLogin?: (params: ILoginParams) => Promise<ILoginResponse | void>\r\n onLogout?: () => Promise<boolean | void>\r\n\r\n // Initial state\r\n initialState?: IAuthState\r\n\r\n // Direct auth data - allows updating state directly from external sources\r\n // Main approach for real-world applications with their own authentication services\r\n authData?: {\r\n id?: string\r\n displayName?: string\r\n email?: string\r\n avatar?: string\r\n roles?: string[]\r\n [key: string]: any // Allow custom fields\r\n }\r\n\r\n // Auth state subscription\r\n // Allows registering callbacks to receive notifications when auth state changes from external services\r\n onAuthChange?: (callback: (newState: IAuthState) => void) => () => void\r\n}\r\n\r\n/**\r\n * AuthProvider - Component for Host application\r\n *\r\n * Manages authentication state and broadcasts events to MFEs.\r\n * Place this component anywhere in your application, no need to wrap other components.\r\n *\r\n * Host can customize login/logout behavior by providing custom handlers.\r\n */\r\nexport const AuthProvider: React.FC<IAuthProviderProps> = ({\r\n children,\r\n onLogin,\r\n onLogout,\r\n initialState = INITIAL_AUTH_STATE,\r\n authData,\r\n onAuthChange\r\n}) => {\r\n // Authentication state\r\n const [authState, setAuthState] = useState<IAuthState>(initialState)\r\n\r\n // Handle when authData is provided directly and changes\r\n useEffect(() => {\r\n if (authData) {\r\n // Convert from authData to AuthState\r\n\r\n let user: IUser | null = null\r\n if (authData.id || authData.displayName) {\r\n user = {\r\n id: authData.id || 'unknown',\r\n displayName: authData.displayName || 'Unknown User',\r\n email: authData.email || '',\r\n roles: authData.roles || [],\r\n avatar: authData.avatar\r\n }\r\n }\r\n const isAuthenticated = !!authData.id || !!authData.displayName\r\n const newState: IAuthState = { \r\n isAuthenticated, \r\n isLoading: false, \r\n user, \r\n error: null,\r\n // Mark if running in SSR environment\r\n serverRendered: !isBrowser()\r\n }\r\n // Update state and notify MFEs\r\n setAuthState(newState)\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, newState)\r\n }\r\n }, [authData]) // Re-run when authData changes\r\n\r\n // Register with onAuthChange if provided\r\n useEffect(() => {\r\n if (onAuthChange) {\r\n // Register callback to receive notifications when auth changes from external service\r\n const unsubscribe = onAuthChange((newState) => {\r\n setAuthState(newState)\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, newState)\r\n })\r\n\r\n return unsubscribe\r\n }\r\n }, [onAuthChange])\r\n\r\n useEffect(() => {\r\n // Listen for requests from MFEs\r\n const unsubscribeRequestState = mfeBridge.subscribe(AUTH_CHANNELS.REQUEST_STATE, () => {\r\n // Send current state when requested by an MFE\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, authState)\r\n })\r\n\r\n const unsubscribeLogin = mfeBridge.subscribe(AUTH_CHANNELS.LOGIN, (credentials) => {\r\n handleLogin(credentials.username, credentials.password)\r\n })\r\n\r\n const unsubscribeLogout = mfeBridge.subscribe(AUTH_CHANNELS.LOGOUT, () => {\r\n handleLogout()\r\n })\r\n\r\n return () => {\r\n unsubscribeRequestState()\r\n unsubscribeLogin()\r\n unsubscribeLogout()\r\n }\r\n }, [authState])\r\n\r\n // Login handler - uses onLogin from props if provided\r\n const handleLogin = async (username: string, password: string) => {\r\n setAuthState((prev) => ({ ...prev, isLoading: true, error: null }))\r\n\r\n try {\r\n // Use provided login handler if available\r\n if (onLogin) {\r\n const result = await onLogin({ username, password })\r\n \r\n // If onLogin returns login response data, use it to update state\r\n if (result) {\r\n const newState: IAuthState = {\r\n isAuthenticated: result.isAuthenticated,\r\n isLoading: false,\r\n user: result.user || null,\r\n error: result.error || null,\r\n serverRendered: !isBrowser()\r\n }\r\n \r\n setAuthState(newState)\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, newState)\r\n } else {\r\n // If onLogin doesn't return data, just set loading to false\r\n // This allows the host app to handle the auth flow completely\r\n setAuthState(prev => ({ ...prev, isLoading: false }))\r\n }\r\n } else {\r\n // No default handling in library mode\r\n throw new Error('No login handler provided. Please provide an onLogin handler to AuthProvider.')\r\n }\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : 'Login failed'\r\n const errorState: IAuthState = { \r\n isAuthenticated: false, \r\n isLoading: false, \r\n user: null, \r\n error: message,\r\n serverRendered: !isBrowser()\r\n }\r\n setAuthState(errorState)\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, errorState)\r\n }\r\n }\r\n\r\n // Logout handler - uses onLogout from props if provided\r\n const handleLogout = async () => {\r\n setAuthState((prev) => ({ ...prev, isLoading: true }))\r\n\r\n try {\r\n // Use provided logout handler if available\r\n if (onLogout) {\r\n const result = await onLogout()\r\n \r\n // If onLogout returns a boolean, use it to determine success\r\n // If it returns nothing (void), assume success\r\n if (result !== false) {\r\n const newState: IAuthState = { \r\n isAuthenticated: false, \r\n isLoading: false, \r\n user: null, \r\n error: null,\r\n serverRendered: !isBrowser()\r\n }\r\n setAuthState(newState)\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, newState)\r\n } else {\r\n throw new Error('Logout failed')\r\n }\r\n } else {\r\n // No default handling in library mode\r\n throw new Error('No logout handler provided. Please provide an onLogout handler to AuthProvider.')\r\n }\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : 'Logout failed'\r\n setAuthState((prev) => ({ ...prev, isLoading: false, error: message }))\r\n }\r\n }\r\n\r\n // Simply return children\r\n return <>{children}</>\r\n}\r\n\r\n// Hook for using Auth in both host and MFE\r\nexport function useAuth() {\r\n const [authState, setAuthState] = useState<IAuthState>(INITIAL_AUTH_STATE)\r\n\r\n useEffect(() => {\r\n // Subscribe to authentication state changes from provider\r\n const unsubscribe = mfeBridge.subscribe<IAuthState>(AUTH_CHANNELS.STATE_CHANGE, (newState) => {\r\n setAuthState(newState)\r\n })\r\n\r\n // Request current state\r\n mfeBridge.publish(AUTH_CHANNELS.REQUEST_STATE, null)\r\n\r\n return unsubscribe\r\n }, [])\r\n\r\n // Functions always use mfeBridge for communication\r\n const login = (username: string, password: string) => {\r\n mfeBridge.publish(AUTH_CHANNELS.LOGIN, { username, password })\r\n }\r\n\r\n const logout = () => {\r\n mfeBridge.publish(AUTH_CHANNELS.LOGOUT, null)\r\n }\r\n\r\n return { ...authState, login, logout }\r\n}\r\n"],"names":["AuthProvider","_ref","children","onLogin","onLogout","_ref$initialState","initialState","INITIAL_AUTH_STATE","authData","onAuthChange","_useState","useState","_useState2","_slicedToArray","authState","setAuthState","useEffect","user","id","displayName","email","roles","avatar","newState","isAuthenticated","isLoading","error","serverRendered","isBrowser","mfeBridge","publish","AUTH_CHANNELS","STATE_CHANGE","unsubscribeRequestState","subscribe","REQUEST_STATE","unsubscribeLogin","LOGIN","credentials","handleLogin","username","password","unsubscribeLogout","LOGOUT","handleLogout","_ref2","_asyncToGenerator","_regenerator","m","_callee","result","message","errorState","_t","w","_context","n","prev","_objectSpread","p","v","Error","a","_x","_x2","apply","this","arguments","_ref3","_callee2","_t2","_context2","_jsx","_Fragment","useAuth","_useState3","_useState4","unsubscribe","login","logout"],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sources":["../../src/mfe-shared/auth.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react'\r\nimport { mfeBridge } from './mfe-bridge'\r\nimport { AUTH_CHANNELS, IAuthState, INITIAL_AUTH_STATE, IUser } from './auth.types'\r\nimport { isBrowser } from './environment'\r\n\r\n/**\r\n * Login parameters structure\r\n */\r\nexport interface ILoginParams {\r\n username: string\r\n password: string\r\n}\r\n\r\n/**\r\n * Login response structure\r\n */\r\nexport interface ILoginResponse {\r\n isAuthenticated: boolean\r\n user?: IUser\r\n error?: string\r\n}\r\n\r\nexport interface IMfeAuthProviderProps {\r\n children?: React.ReactNode\r\n\r\n // Custom handlers for manual authentication\r\n // onLogin can simply trigger authentication (like opening a login modal) without returning immediate data\r\n onLogin?: (params: ILoginParams) => Promise<ILoginResponse | void>\r\n onLogout?: () => Promise<boolean | void>\r\n\r\n // Initial state\r\n initialState?: IAuthState\r\n\r\n // Direct auth data - allows updating state directly from external sources\r\n // Main approach for real-world applications with their own authentication services\r\n authData?: {\r\n id?: string\r\n displayName?: string\r\n email?: string\r\n avatar?: string\r\n roles?: string[]\r\n [key: string]: any // Allow custom fields\r\n }\r\n\r\n // Auth state subscription\r\n // Allows registering callbacks to receive notifications when auth state changes from external services\r\n onAuthChange?: (callback: (newState: IAuthState) => void) => () => void\r\n}\r\n\r\n/**\r\n * AuthProvider - Component for Host application\r\n *\r\n * Manages authentication state and broadcasts events to MFEs.\r\n * Place this component anywhere in your application, no need to wrap other components.\r\n *\r\n * Host can customize login/logout behavior by providing custom handlers.\r\n */\r\nexport const MfeAuthProvider: React.FC<IMfeAuthProviderProps> = ({\r\n children,\r\n onLogin,\r\n onLogout,\r\n initialState = INITIAL_AUTH_STATE,\r\n authData,\r\n onAuthChange\r\n}) => {\r\n // Authentication state\r\n const [authState, setAuthState] = useState<IAuthState>(initialState)\r\n\r\n // Handle when authData is provided directly and changes\r\n useEffect(() => {\r\n if (authData) {\r\n // Convert from authData to AuthState\r\n\r\n let user: IUser | null = null\r\n if (authData.id || authData.displayName) {\r\n user = {\r\n id: authData.id || 'unknown',\r\n displayName: authData.displayName || 'Unknown User',\r\n email: authData.email || '',\r\n roles: authData.roles || [],\r\n avatar: authData.avatar\r\n }\r\n }\r\n const isAuthenticated = !!authData.id || !!authData.displayName\r\n const newState: IAuthState = {\r\n isAuthenticated,\r\n isLoading: false,\r\n user,\r\n error: null,\r\n // Mark if running in SSR environment\r\n serverRendered: !isBrowser()\r\n }\r\n // Update state and notify MFEs\r\n setAuthState(newState)\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, newState)\r\n }\r\n }, [authData]) // Re-run when authData changes\r\n\r\n // Register with onAuthChange if provided\r\n useEffect(() => {\r\n if (onAuthChange) {\r\n // Register callback to receive notifications when auth changes from external service\r\n const unsubscribe = onAuthChange((newState) => {\r\n setAuthState(newState)\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, newState)\r\n })\r\n\r\n return unsubscribe\r\n }\r\n }, [onAuthChange])\r\n\r\n useEffect(() => {\r\n // Listen for requests from MFEs\r\n const unsubscribeRequestState = mfeBridge.subscribe(AUTH_CHANNELS.REQUEST_STATE, () => {\r\n // Send current state when requested by an MFE\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, authState)\r\n })\r\n\r\n const unsubscribeLogin = mfeBridge.subscribe(AUTH_CHANNELS.LOGIN, (credentials) => {\r\n handleLogin(credentials.username, credentials.password)\r\n })\r\n\r\n const unsubscribeLogout = mfeBridge.subscribe(AUTH_CHANNELS.LOGOUT, () => {\r\n handleLogout()\r\n })\r\n\r\n return () => {\r\n unsubscribeRequestState()\r\n unsubscribeLogin()\r\n unsubscribeLogout()\r\n }\r\n }, [authState])\r\n\r\n // Login handler - uses onLogin from props if provided\r\n const handleLogin = async (username: string, password: string) => {\r\n setAuthState((prev) => ({ ...prev, isLoading: true, error: null }))\r\n\r\n try {\r\n // Use provided login handler if available\r\n if (onLogin) {\r\n const result = await onLogin({ username, password })\r\n\r\n // If onLogin returns login response data, use it to update state\r\n if (result) {\r\n const newState: IAuthState = {\r\n isAuthenticated: result.isAuthenticated,\r\n isLoading: false,\r\n user: result.user || null,\r\n error: result.error || null,\r\n serverRendered: !isBrowser()\r\n }\r\n\r\n setAuthState(newState)\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, newState)\r\n } else {\r\n // If onLogin doesn't return data, just set loading to false\r\n // This allows the host app to handle the auth flow completely\r\n setAuthState((prev) => ({ ...prev, isLoading: false }))\r\n }\r\n } else {\r\n // No default handling in library mode\r\n throw new Error('No login handler provided. Please provide an onLogin handler to AuthProvider.')\r\n }\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : 'Login failed'\r\n const errorState: IAuthState = {\r\n isAuthenticated: false,\r\n isLoading: false,\r\n user: null,\r\n error: message,\r\n serverRendered: !isBrowser()\r\n }\r\n setAuthState(errorState)\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, errorState)\r\n }\r\n }\r\n\r\n // Logout handler - uses onLogout from props if provided\r\n const handleLogout = async () => {\r\n setAuthState((prev) => ({ ...prev, isLoading: true }))\r\n\r\n try {\r\n // Use provided logout handler if available\r\n if (onLogout) {\r\n const result = await onLogout()\r\n\r\n // If onLogout returns a boolean, use it to determine success\r\n // If it returns nothing (void), assume success\r\n if (result !== false) {\r\n const newState: IAuthState = {\r\n isAuthenticated: false,\r\n isLoading: false,\r\n user: null,\r\n error: null,\r\n serverRendered: !isBrowser()\r\n }\r\n setAuthState(newState)\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, newState)\r\n } else {\r\n throw new Error('Logout failed')\r\n }\r\n } else {\r\n // No default handling in library mode\r\n throw new Error('No logout handler provided. Please provide an onLogout handler to AuthProvider.')\r\n }\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : 'Logout failed'\r\n setAuthState((prev) => ({ ...prev, isLoading: false, error: message }))\r\n }\r\n }\r\n\r\n // Simply return children\r\n return <>{children}</>\r\n}\r\n\r\n// Hook for using micro-frontend Auth in both host and MFE\r\nexport function useMfeAuth() {\r\n const [authState, setAuthState] = useState<IAuthState>(INITIAL_AUTH_STATE)\r\n\r\n useEffect(() => {\r\n // Subscribe to authentication state changes from provider\r\n const unsubscribe = mfeBridge.subscribe<IAuthState>(AUTH_CHANNELS.STATE_CHANGE, (newState) => {\r\n setAuthState(newState)\r\n })\r\n\r\n // Request current state\r\n mfeBridge.publish(AUTH_CHANNELS.REQUEST_STATE, null)\r\n\r\n return unsubscribe\r\n }, [])\r\n\r\n // Functions always use mfeBridge for communication\r\n const login = (username: string, password: string) => {\r\n mfeBridge.publish(AUTH_CHANNELS.LOGIN, { username, password })\r\n }\r\n\r\n const logout = () => {\r\n mfeBridge.publish(AUTH_CHANNELS.LOGOUT, null)\r\n }\r\n\r\n return { ...authState, login, logout }\r\n}\r\n"],"names":["MfeAuthProvider","_ref","children","onLogin","onLogout","_ref$initialState","initialState","INITIAL_AUTH_STATE","authData","onAuthChange","_useState","useState","_useState2","_slicedToArray","authState","setAuthState","useEffect","user","id","displayName","email","roles","avatar","newState","isAuthenticated","isLoading","error","serverRendered","isBrowser","mfeBridge","publish","AUTH_CHANNELS","STATE_CHANGE","unsubscribeRequestState","subscribe","REQUEST_STATE","unsubscribeLogin","LOGIN","credentials","handleLogin","username","password","unsubscribeLogout","LOGOUT","handleLogout","_ref2","_asyncToGenerator","_regenerator","m","_callee","result","message","errorState","_t","w","_context","n","prev","_objectSpread","p","v","Error","a","_x","_x2","apply","this","arguments","_ref3","_callee2","_t2","_context2","_jsx","_Fragment","useMfeAuth","_useState3","_useState4","unsubscribe","login","logout"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{objectSpread2 as r}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsx as t}from"react/jsx-runtime";import{INITIAL_AUTH_STATE as e}from"./auth.types.js";import{AuthProvider as o}from"./auth.js";import{HydrationGuard as a}from"./hydration-helper.js";var n=function(n){var i=n.children,u=n.initialAuthState,h=n.userData,l=n.authData,s=n.onLogin,d=n.onLogout,m=n.onAuthChange,p=u;return!p&&h&&(p={isAuthenticated:!0,isLoading:!1,user:h,error:null,serverRendered:!0}),t(o,{initialState:p||r(r({},e),{},{serverRendered:!0}),authData:l,onLogin:s,onLogout:d,onAuthChange:m,children:t(a,{children:i})})};export{n as SsrAuthProvider};
1
+ import{objectSpread2 as r}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsx as t}from"react/jsx-runtime";import{INITIAL_AUTH_STATE as e}from"./auth.types.js";import{MfeAuthProvider as o}from"./auth.js";import{HydrationGuard as a}from"./hydration-helper.js";var n=function(n){var i=n.children,u=n.initialAuthState,h=n.userData,l=n.authData,s=n.onLogin,d=n.onLogout,m=n.onAuthChange,p=u;return!p&&h&&(p={isAuthenticated:!0,isLoading:!1,user:h,error:null,serverRendered:!0}),t(o,{initialState:p||r(r({},e),{},{serverRendered:!0}),authData:l,onLogin:s,onLogout:d,onAuthChange:m,children:t(a,{children:i})})};export{n as SsrAuthProvider};
2
2
  //# sourceMappingURL=auth.ssr.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.ssr.js","sources":["../../src/mfe-shared/auth.ssr.tsx"],"sourcesContent":["import React from 'react'\r\nimport { IAuthState, INITIAL_AUTH_STATE, IUser } from './auth.types'\r\nimport { AuthProvider, type IAuthProviderProps } from './auth'\r\nimport { HydrationGuard } from './hydration-helper'\r\n\r\n/**\r\n * Props for the SSR-compatible auth provider\r\n */\r\ninterface ISsrAuthProviderProps {\r\n /** Content to render */\r\n children: React.ReactNode\r\n /** Initial auth state for SSR */\r\n initialAuthState?: IAuthState\r\n /** User data for initial state */\r\n userData?: IUser\r\n /** Custom auth data to be passed to AuthProvider */\r\n authData?: {\r\n id?: string\r\n displayName?: string\r\n email?: string\r\n avatar?: string\r\n roles?: string[]\r\n [key: string]: any\r\n }\r\n /** Custom login handler */\r\n onLogin?: IAuthProviderProps['onLogin']\r\n /** Custom logout handler */\r\n onLogout?: IAuthProviderProps['onLogout']\r\n /** Auth state change subscription */\r\n onAuthChange?: IAuthProviderProps['onAuthChange']\r\n}\r\n\r\n/**\r\n * Auth provider component that supports SSR\r\n * \r\n * This component allows providing initial auth data during server-side rendering\r\n * and then hydrating from API or other sources once client-side.\r\n */\r\nexport const SsrAuthProvider: React.FC<ISsrAuthProviderProps> = ({\r\n children,\r\n initialAuthState,\r\n userData,\r\n authData,\r\n onLogin,\r\n onLogout,\r\n onAuthChange\r\n}) => {\r\n // Prepare auth state for SSR\r\n let ssrAuthState = initialAuthState\r\n \r\n // If userData is provided but not initialAuthState, create auth state from userData\r\n if (!ssrAuthState && userData) {\r\n ssrAuthState = {\r\n isAuthenticated: true,\r\n isLoading: false,\r\n user: userData,\r\n error: null,\r\n serverRendered: true\r\n }\r\n }\r\n\r\n return (\r\n <AuthProvider\r\n initialState={ssrAuthState || { ...INITIAL_AUTH_STATE, serverRendered: true }}\r\n authData={authData}\r\n onLogin={onLogin}\r\n onLogout={onLogout}\r\n onAuthChange={onAuthChange}\r\n >\r\n <HydrationGuard>\r\n {children}\r\n </HydrationGuard>\r\n </AuthProvider>\r\n )\r\n}\r\n\r\n/**\r\n * Props for the SSR-compatible authenticated content component\r\n */\r\ninterface IAuthenticatedContentProps {\r\n /** Content to show when authenticated */\r\n children: React.ReactNode\r\n /** Content to show when not authenticated */\r\n fallback?: React.ReactNode\r\n /** Initial authentication state for SSR */\r\n initiallyAuthenticated?: boolean\r\n}\r\n\r\n/**\r\n * Component that conditionally renders content based on authentication state\r\n * with SSR support\r\n */\r\nexport const AuthenticatedContent: React.FC<IAuthenticatedContentProps> = ({\r\n children,\r\n fallback,\r\n initiallyAuthenticated = false\r\n}) => {\r\n // Let the AuthProvider handle hydration - we just need to render the right content\r\n return (\r\n <HydrationGuard\r\n serverFallback={initiallyAuthenticated ? <>{children}</> : <>{fallback}</>}\r\n >\r\n {/* Regular content will be rendered during hydration and after */}\r\n {children}\r\n </HydrationGuard>\r\n )\r\n}\r\n"],"names":["SsrAuthProvider","_ref","children","initialAuthState","userData","authData","onLogin","onLogout","onAuthChange","ssrAuthState","isAuthenticated","isLoading","user","error","serverRendered","_jsx","AuthProvider","initialState","_objectSpread","INITIAL_AUTH_STATE","HydrationGuard"],"mappings":"0QAsCaA,EAAmD,SAApCC,GAQvB,IAPHC,EAAQD,EAARC,SACAC,EAAgBF,EAAhBE,iBACAC,EAAQH,EAARG,SACAC,EAAQJ,EAARI,SACAC,EAAOL,EAAPK,QACAC,EAAQN,EAARM,SACAC,EAAYP,EAAZO,aAGIC,EAAeN,EAanB,OAVKM,GAAgBL,IACnBK,EAAe,CACbC,iBAAiB,EACjBC,WAAW,EACXC,KAAMR,EACNS,MAAO,KACPC,gBAAgB,IAKlBC,EAACC,GACCC,aAAcR,GAAYS,EAAAA,KAASC,GAAkB,GAAA,CAAEL,gBAAgB,IACvET,SAAUA,EACVC,QAASA,EACTC,SAAUA,EACVC,aAAcA,EAAYN,SAE1Ba,EAACK,EAAc,CAAAlB,SACZA,KAIT"}
1
+ {"version":3,"file":"auth.ssr.js","sources":["../../src/mfe-shared/auth.ssr.tsx"],"sourcesContent":["import React from 'react'\r\nimport { IAuthState, INITIAL_AUTH_STATE, IUser } from './auth.types'\r\nimport { MfeAuthProvider, type IMfeAuthProviderProps } from './auth'\r\nimport { HydrationGuard } from './hydration-helper'\r\n\r\n/**\r\n * Props for the SSR-compatible auth provider\r\n */\r\ninterface ISsrAuthProviderProps {\r\n /** Content to render */\r\n children: React.ReactNode\r\n /** Initial auth state for SSR */\r\n initialAuthState?: IAuthState\r\n /** User data for initial state */\r\n userData?: IUser\r\n /** Custom auth data to be passed to AuthProvider */\r\n authData?: {\r\n id?: string\r\n displayName?: string\r\n email?: string\r\n avatar?: string\r\n roles?: string[]\r\n [key: string]: any\r\n }\r\n /** Custom login handler */\r\n onLogin?: IMfeAuthProviderProps['onLogin']\r\n /** Custom logout handler */\r\n onLogout?: IMfeAuthProviderProps['onLogout']\r\n /** Auth state change subscription */\r\n onAuthChange?: IMfeAuthProviderProps['onAuthChange']\r\n}\r\n\r\n/**\r\n * Auth provider component that supports SSR\r\n * \r\n * This component allows providing initial auth data during server-side rendering\r\n * and then hydrating from API or other sources once client-side.\r\n */\r\nexport const SsrAuthProvider: React.FC<ISsrAuthProviderProps> = ({\r\n children,\r\n initialAuthState,\r\n userData,\r\n authData,\r\n onLogin,\r\n onLogout,\r\n onAuthChange\r\n}) => {\r\n // Prepare auth state for SSR\r\n let ssrAuthState = initialAuthState\r\n \r\n // If userData is provided but not initialAuthState, create auth state from userData\r\n if (!ssrAuthState && userData) {\r\n ssrAuthState = {\r\n isAuthenticated: true,\r\n isLoading: false,\r\n user: userData,\r\n error: null,\r\n serverRendered: true\r\n }\r\n }\r\n\r\n return (\r\n <MfeAuthProvider\r\n initialState={ssrAuthState || { ...INITIAL_AUTH_STATE, serverRendered: true }}\r\n authData={authData}\r\n onLogin={onLogin}\r\n onLogout={onLogout}\r\n onAuthChange={onAuthChange}\r\n >\r\n <HydrationGuard>\r\n {children}\r\n </HydrationGuard>\r\n </MfeAuthProvider>\r\n )\r\n}\r\n\r\n/**\r\n * Props for the SSR-compatible authenticated content component\r\n */\r\ninterface IAuthenticatedContentProps {\r\n /** Content to show when authenticated */\r\n children: React.ReactNode\r\n /** Content to show when not authenticated */\r\n fallback?: React.ReactNode\r\n /** Initial authentication state for SSR */\r\n initiallyAuthenticated?: boolean\r\n}\r\n\r\n/**\r\n * Component that conditionally renders content based on authentication state\r\n * with SSR support\r\n */\r\nexport const AuthenticatedContent: React.FC<IAuthenticatedContentProps> = ({\r\n children,\r\n fallback,\r\n initiallyAuthenticated = false\r\n}) => {\r\n // Let the AuthProvider handle hydration - we just need to render the right content\r\n return (\r\n <HydrationGuard\r\n serverFallback={initiallyAuthenticated ? <>{children}</> : <>{fallback}</>}\r\n >\r\n {/* Regular content will be rendered during hydration and after */}\r\n {children}\r\n </HydrationGuard>\r\n )\r\n}\r\n"],"names":["SsrAuthProvider","_ref","children","initialAuthState","userData","authData","onLogin","onLogout","onAuthChange","ssrAuthState","isAuthenticated","isLoading","user","error","serverRendered","_jsx","MfeAuthProvider","initialState","_objectSpread","INITIAL_AUTH_STATE","HydrationGuard"],"mappings":"6QAsCaA,EAAmD,SAApCC,GAQvB,IAPHC,EAAQD,EAARC,SACAC,EAAgBF,EAAhBE,iBACAC,EAAQH,EAARG,SACAC,EAAQJ,EAARI,SACAC,EAAOL,EAAPK,QACAC,EAAQN,EAARM,SACAC,EAAYP,EAAZO,aAGIC,EAAeN,EAanB,OAVKM,GAAgBL,IACnBK,EAAe,CACbC,iBAAiB,EACjBC,WAAW,EACXC,KAAMR,EACNS,MAAO,KACPC,gBAAgB,IAKlBC,EAACC,GACCC,aAAcR,GAAYS,EAAAA,KAASC,GAAkB,GAAA,CAAEL,gBAAgB,IACvET,SAAUA,EACVC,QAASA,EACTC,SAAUA,EACVC,aAAcA,EAAYN,SAE1Ba,EAACK,EAAc,CAAAlB,SACZA,KAIT"}
@@ -0,0 +1,2 @@
1
+ import{slicedToArray as e,objectSpread2 as t,defineProperty as r,toConsumableArray as n}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsxs as i,jsx as a}from"react/jsx-runtime";import{useState as o,useEffect as l}from"react";var d=function(d){var c,s,u=o({}),f=e(u,2),m=f[0],p=f[1],v=d.channelPrefix||"mfe:cart:";return l((function(){var e=["mfe:cart:add","mfe:cart:remove","mfe:cart:clear","mfe:cart:init_request","mfe:cart:init_response","mfe:cart:update"],i=function(e){var i=e,a=i.type;i.detail&&a.startsWith(v)&&p((function(e){var o,l,d=(null===(o=e[a])||void 0===o?void 0:o.history)||[];return t(t({},e),{},r({},a,{channel:a,history:[].concat(n(d),[{channel:a,payload:(null===(l=i.detail)||void 0===l?void 0:l.payload)||i.detail,timestamp:Date.now()}]).slice(-20)}))}))};return e.forEach((function(e){window.addEventListener(e,i)})),function(){e.forEach((function(e){window.removeEventListener(e,i)}))}}),[v]),i("div",{style:t({position:"fixed",width:400,maxHeight:400,overflow:"auto",background:"#222",color:"#fff",zIndex:9999,fontSize:12,padding:8,borderRadius:8},null!==(c=d.style)&&void 0!==c?c:{bottom:0,right:0}),children:[a("strong",{children:null!==(s=d.title)&&void 0!==s?s:"MFE Event Bridge Debug Panel"}),0===Object.values(m).length&&a("div",{children:"No event activity yet."}),Object.values(m).map((function(e){return i("div",{style:{marginTop:8,borderTop:"1px solid #444",paddingTop:4},children:[i("div",{children:[a("b",{children:"Channel:"})," ",e.channel]}),a("div",{style:{maxHeight:120,overflow:"auto",background:"#333",padding:4,borderRadius:4},children:e.history.map((function(e,t){return i("div",{style:{marginBottom:2},children:[i("span",{style:{color:"#aaa"},children:[new Date(e.timestamp).toLocaleTimeString(),":"]}),a("pre",{style:{display:"inline",margin:0,color:"#0f0"},children:JSON.stringify(e.payload,null,2)})]},t)}))})]},e.channel)}))]})};export{d as MfeCartDebugPanel,d as default};
2
+ //# sourceMappingURL=cart.debug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cart.debug.js","sources":["../../src/mfe-shared/cart.debug.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react'\r\n\r\ninterface IEventHistoryEntry {\r\n channel: string\r\n payload: any\r\n timestamp: number\r\n}\r\n\r\ninterface IEventDebugData {\r\n channel: string\r\n history: IEventHistoryEntry[]\r\n}\r\n\r\ninterface IDebugPanelProps {\r\n title?: string\r\n style?: React.CSSProperties\r\n channelPrefix?: string\r\n}\r\n\r\nexport const MfeCartDebugPanel: React.FC<IDebugPanelProps> = (props) => {\r\n const [events, setEvents] = useState<Record<string, IEventDebugData>>({})\r\n const channelPrefix = props.channelPrefix || 'mfe:cart:'\r\n\r\n useEffect(() => {\r\n const cartChannels = ['mfe:cart:add', 'mfe:cart:remove', 'mfe:cart:clear', 'mfe:cart:init_request', 'mfe:cart:init_response', 'mfe:cart:update']\r\n\r\n const handleEvent = (e: Event) => {\r\n const customEvent = e as CustomEvent\r\n const channel = customEvent.type\r\n\r\n if (customEvent.detail && channel.startsWith(channelPrefix)) {\r\n setEvents((prev) => {\r\n const prevHistory = prev[channel]?.history || []\r\n return {\r\n ...prev,\r\n [channel]: {\r\n channel,\r\n history: [\r\n ...prevHistory,\r\n {\r\n channel,\r\n payload: customEvent.detail?.payload || customEvent.detail,\r\n timestamp: Date.now()\r\n }\r\n ].slice(-20) // keep last 20\r\n }\r\n }\r\n })\r\n }\r\n }\r\n\r\n // Listen to cart events\r\n cartChannels.forEach((channel) => {\r\n window.addEventListener(channel, handleEvent)\r\n })\r\n\r\n // Clean up\r\n return () => {\r\n cartChannels.forEach((channel) => {\r\n window.removeEventListener(channel, handleEvent)\r\n })\r\n }\r\n }, [channelPrefix])\r\n\r\n return (\r\n <div\r\n style={{\r\n position: 'fixed',\r\n width: 400,\r\n maxHeight: 400,\r\n overflow: 'auto',\r\n background: '#222',\r\n color: '#fff',\r\n zIndex: 9999,\r\n fontSize: 12,\r\n padding: 8,\r\n borderRadius: 8,\r\n ...(props.style ?? { bottom: 0, right: 0 })\r\n }}\r\n >\r\n <strong>{props.title ?? 'MFE Event Bridge Debug Panel'}</strong>\r\n {Object.values(events).length === 0 && <div>No event activity yet.</div>}\r\n {Object.values(events).map((eventData) => (\r\n <div key={eventData.channel} style={{ marginTop: 8, borderTop: '1px solid #444', paddingTop: 4 }}>\r\n <div>\r\n <b>Channel:</b> {eventData.channel}\r\n </div>\r\n <div style={{ maxHeight: 120, overflow: 'auto', background: '#333', padding: 4, borderRadius: 4 }}>\r\n {eventData.history.map((entry, idx) => (\r\n <div key={idx} style={{ marginBottom: 2 }}>\r\n <span style={{ color: '#aaa' }}>{new Date(entry.timestamp).toLocaleTimeString()}:</span>\r\n <pre style={{ display: 'inline', margin: 0, color: '#0f0' }}>{JSON.stringify(entry.payload, null, 2)}</pre>\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n )\r\n}\r\n\r\nexport default MfeCartDebugPanel\r\n"],"names":["MfeCartDebugPanel","props","_props$style","_props$title","_useState","useState","_useState2","_slicedToArray","events","setEvents","channelPrefix","useEffect","cartChannels","handleEvent","e","customEvent","channel","type","detail","startsWith","prev","_prev$channel","_customEvent$detail","prevHistory","history","_objectSpread","_defineProperty","concat","_toConsumableArray","payload","timestamp","Date","now","slice","forEach","window","addEventListener","removeEventListener","_jsxs","style","position","width","maxHeight","overflow","background","color","zIndex","fontSize","padding","borderRadius","bottom","right","children","_jsx","title","Object","values","length","map","eventData","marginTop","borderTop","paddingTop","entry","idx","marginBottom","toLocaleTimeString","display","margin","JSON","stringify"],"mappings":"6OAmBaA,EAAgD,SAACC,GAAS,IAAAC,EAAAC,EACrEC,EAA4BC,EAA0C,IAAGC,EAAAC,EAAAH,EAAA,GAAlEI,EAAMF,EAAA,GAAEG,EAASH,EAAA,GAClBI,EAAgBT,EAAMS,eAAiB,YA2C7C,OAzCAC,GAAU,WACR,IAAMC,EAAe,CAAC,eAAgB,kBAAmB,iBAAkB,wBAAyB,yBAA0B,mBAExHC,EAAc,SAACC,GACnB,IAAMC,EAAcD,EACdE,EAAUD,EAAYE,KAExBF,EAAYG,QAAUF,EAAQG,WAAWT,IAC3CD,GAAU,SAACW,GAAQ,IAAAC,EAAAC,EACXC,GAA2B,QAAbF,EAAAD,EAAKJ,UAALK,IAAaA,OAAbA,EAAAA,EAAeG,UAAW,GAC9C,OAAAC,EAAAA,EAAA,GACKL,GAAIM,GAAAA,EACNV,CAAAA,EAAAA,EAAU,CACTA,QAAAA,EACAQ,QAAS,GAAAG,OAAAC,EACJL,GACH,CAAA,CACEP,QAAAA,EACAa,SAA2B,QAAlBP,EAAAP,EAAYG,cAAM,IAAAI,OAAA,EAAlBA,EAAoBO,UAAWd,EAAYG,OACpDY,UAAWC,KAAKC,SAElBC,aAGR,GAEH,EAQD,OALArB,EAAasB,SAAQ,SAAClB,GACpBmB,OAAOC,iBAAiBpB,EAASH,EACnC,IAGO,WACLD,EAAasB,SAAQ,SAAClB,GACpBmB,OAAOE,oBAAoBrB,EAASH,EACtC,GACD,CACH,GAAG,CAACH,IAGF4B,EACE,MAAA,CAAAC,MAAKd,EAAA,CACHe,SAAU,QACVC,MAAO,IACPC,UAAW,IACXC,SAAU,OACVC,WAAY,OACZC,MAAO,OACPC,OAAQ,KACRC,SAAU,GACVC,QAAS,EACTC,aAAc,GACC/C,QADAA,EACXD,EAAMsC,aAAKrC,IAAAA,EAAAA,EAAI,CAAEgD,OAAQ,EAAGC,MAAO,IACxCC,SAAA,CAEDC,qBAAoBlD,UAAXF,EAAMqD,aAAKnD,IAAAA,EAAAA,EAAI,iCACU,IAAjCoD,OAAOC,OAAOhD,GAAQiD,QAAgBJ,EAAA,MAAA,CAAAD,SAAA,2BACtCG,OAAOC,OAAOhD,GAAQkD,KAAI,SAACC,GAAS,OACnCrB,SAA6BC,MAAO,CAAEqB,UAAW,EAAGC,UAAW,iBAAkBC,WAAY,GAAGV,SAAA,CAC9Fd,EACE,MAAA,CAAAc,SAAA,CAAAC,EAAA,IAAA,CAAAD,SAAA,iBAAiBO,EAAU3C,WAE7BqC,SAAKd,MAAO,CAAEG,UAAW,IAAKC,SAAU,OAAQC,WAAY,OAAQI,QAAS,EAAGC,aAAc,GAC3FG,SAAAO,EAAUnC,QAAQkC,KAAI,SAACK,EAAOC,GAAG,OAChC1B,SAAeC,MAAO,CAAE0B,aAAc,GAAGb,SAAA,CACvCd,EAAM,OAAA,CAAAC,MAAO,CAAEM,MAAO,kBAAW,IAAId,KAAKgC,EAAMjC,WAAWoC,qBAAoB,OAC/Eb,EAAK,MAAA,CAAAd,MAAO,CAAE4B,QAAS,SAAUC,OAAQ,EAAGvB,MAAO,QAAWO,SAAAiB,KAAKC,UAAUP,EAAMlC,QAAS,KAAM,OAF1FmC,EAIX,QAVKL,EAAU3C,QAYd,MAId"}
@@ -1,2 +1,2 @@
1
- import{slicedToArray as r,toConsumableArray as t}from"../_virtual/_rollupPluginBabelHelpers.js";import{useState as e,useRef as n,useEffect as o,useCallback as i}from"react";import{mfeBridge as a}from"./mfe-bridge.js";import{isBrowser as c}from"./environment.js";var u="mfe_cart_items",s={ADD:"mfe:cart:add",REMOVE:"mfe:cart:remove",CLEAR:"mfe:cart:clear",INIT_REQUEST:"mfe:cart:init_request",INIT_RESPONSE:"mfe:cart:init_response",UPDATE:"mfe:cart:update"},l=function(){var i=e([]),l=r(i,2),f=l[0],m=l[1],E=n(!1);return o((function(){if(c()){var r=localStorage.getItem(u);if(r)try{var e=JSON.parse(r);Array.isArray(e)&&(m(e),E.current=!0)}catch(r){console.error("Failed to parse cart from localStorage:",r)}var n=a.subscribe(s.ADD,(function(r){console.log("Item added to cart:",r),m((function(e){var n=[].concat(t(e),[r]);return c()&&localStorage.setItem(u,JSON.stringify(n)),n}))})),o=a.subscribe(s.REMOVE,(function(r){m((function(t){var e=t.filter((function(t){return t.id!==r.id}));return c()&&localStorage.setItem(u,JSON.stringify(e)),e}))})),i=a.subscribe(s.CLEAR,(function(){m([]),c()&&localStorage.removeItem(u)})),l=a.subscribe(s.UPDATE,(function(r){m(r),c()&&localStorage.setItem(u,JSON.stringify(r))})),b=a.subscribe(s.INIT_REQUEST,(function(){f.length>0&&a.publish(s.INIT_RESPONSE,f)})),S=a.subscribe(s.INIT_RESPONSE,(function(r){!E.current&&r&&r.length>0&&(m(r),c()&&localStorage.setItem(u,JSON.stringify(r)),E.current=!0)}));return E.current||a.publish(s.INIT_REQUEST,null),function(){n(),o(),i(),l(),b(),S()}}}),[]),{items:f,totalItems:f.length}},f=function(){return{addToCart:i((function(r){a.publish(s.ADD,r)}),[]),removeFromCart:i((function(r){a.publish(s.REMOVE,{id:r})}),[]),clearCart:i((function(){a.publish(s.CLEAR,null)}),[]),updateCart:i((function(r){a.publish(s.UPDATE,r)}),[])}};export{s as CART_CHANNELS,f as useCartActions,l as useCartStore};
1
+ import{slicedToArray as r,toConsumableArray as t}from"../_virtual/_rollupPluginBabelHelpers.js";import{useMemo as i,useState as e,useRef as n,useEffect as o,useCallback as a}from"react";import{mfeBridge as u}from"./mfe-bridge.js";import{isBrowser as s}from"./environment.js";import{CART_CHANNELS as c}from"./cart.types.js";function l(a){var l=i((function(){return(null==a?void 0:a.storageKey)||"mfe_cart_items"}),[null==a?void 0:a.storageKey]),f=e([]),g=r(f,2),m=g[0],S=g[1],b=n(!1);return o((function(){if(s()){var r=localStorage.getItem(l);if(r)try{var i=JSON.parse(r);Array.isArray(i)&&(S(i),b.current=!0)}catch(r){console.error("Failed to parse cart from localStorage:",r)}var e=u.subscribe(c.ADD,(function(r){S((function(i){var e=[].concat(t(i),[r]);if(JSON.stringify(e)!==JSON.stringify(i)){if(s()){var n=localStorage.getItem(l);JSON.stringify(e)!==n&&localStorage.setItem(l,JSON.stringify(e))}return e}return i}))})),n=u.subscribe(c.REMOVE,(function(r){S((function(t){var i=t.filter((function(t){return t.ProductId!==r.id}));if(JSON.stringify(i)!==JSON.stringify(t)){if(s()){var e=localStorage.getItem(l);JSON.stringify(i)!==e&&localStorage.setItem(l,JSON.stringify(i))}return i}return t}))})),o=u.subscribe(c.CLEAR,(function(){S([]),s()&&localStorage.removeItem(l)})),a=u.subscribe(c.UPDATE,(function(r){S((function(t){if(JSON.stringify(r)!==JSON.stringify(t)){if(s()){var i=localStorage.getItem(l);JSON.stringify(r)!==i&&localStorage.setItem(l,JSON.stringify(r))}return r}return t}))})),f=u.subscribe(c.INIT_REQUEST,(function(){m.length>0&&u.publish(c.INIT_RESPONSE,m)})),g=u.subscribe(c.INIT_RESPONSE,(function(r){!b.current&&r&&r.length>0&&(S(r),s()&&localStorage.setItem(l,JSON.stringify(r)),b.current=!0)}));return b.current||u.publish(c.INIT_REQUEST,null),function(){e(),n(),o(),a(),f(),g()}}}),[]),{items:m,totalItems:m.length}}function f(){return{addToCart:a((function(r){u.publish(c.ADD,r)}),[]),removeFromCart:a((function(r){u.publish(c.REMOVE,{id:r})}),[]),clearCart:a((function(){u.publish(c.CLEAR,null)}),[]),updateCart:a((function(r){u.publish(c.UPDATE,r)}),[])}}export{f as useMfeCartActions,l as useMfeCartStore};
2
2
  //# sourceMappingURL=cart.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cart.js","sources":["../../src/mfe-shared/cart.tsx"],"sourcesContent":["/**\r\n * cart.tsx - Shared shopping cart system for micro-frontends\r\n * \r\n * This module provides hooks for managing a shared shopping cart across\r\n * multiple micro-frontends. The cart state is synchronized using the\r\n * mfeBridge communication system and persisted in localStorage.\r\n */\r\n\r\nimport { useEffect, useState, useRef, useCallback } from 'react'\r\nimport { mfeBridge } from './mfe-bridge'\r\nimport { isBrowser } from './environment'\r\n\r\n/** LocalStorage key for persisting cart items */\r\nconst CART_STORAGE_KEY = 'mfe_cart_items'\r\n\r\n/** Communication channels for cart operations */\r\nexport const CART_CHANNELS = {\r\n /** Add an item to the cart */\r\n ADD: 'mfe:cart:add',\r\n /** Remove an item from the cart */\r\n REMOVE: 'mfe:cart:remove',\r\n /** Clear all items from the cart */\r\n CLEAR: 'mfe:cart:clear',\r\n /** Request initial cart data (when a new MFE loads) */\r\n INIT_REQUEST: 'mfe:cart:init_request',\r\n /** Response with cart data (to initialize a new MFE) */\r\n INIT_RESPONSE: 'mfe:cart:init_response',\r\n /** Update the entire cart at once */\r\n UPDATE: 'mfe:cart:update'\r\n}\r\n\r\n/**\r\n * Shopping cart item structure\r\n */\r\nexport interface ICartItem {\r\n /** Unique identifier for the item */\r\n id: number\r\n /** Display name of the item */\r\n name: string\r\n /** Quantity of this item in the cart */\r\n quantity: number\r\n /** Price per unit of the item */\r\n price: number\r\n}\r\n\r\n/**\r\n * Hook to manage cart state across microFE\r\n * This hook will:\r\n * - Initialize cart from localStorage\r\n * - Listen for cart events (add, remove, clear, update)\r\n * - Provide current cart state\r\n */\r\nexport const useCartStore = () => {\r\n const [items, setItems] = useState<ICartItem[]>([])\r\n\r\n // Mark as initialized\r\n const initialized = useRef(false)\r\n\r\n useEffect(() => {\r\n // Skip localStorage operations in non-browser environments\r\n if (!isBrowser()) {\r\n return;\r\n }\r\n \r\n // Restore from localStorage if available\r\n const storedItems = localStorage.getItem(CART_STORAGE_KEY)\r\n if (storedItems) {\r\n try {\r\n const parsedItems = JSON.parse(storedItems)\r\n if (Array.isArray(parsedItems)) {\r\n setItems(parsedItems)\r\n initialized.current = true\r\n }\r\n } catch (e) {\r\n console.error('Failed to parse cart from localStorage:', e)\r\n }\r\n }\r\n\r\n // Subscribe to cart events\r\n const unsubAdd = mfeBridge.subscribe(CART_CHANNELS.ADD, (payload: ICartItem) => {\r\n console.log('Item added to cart:', payload)\r\n setItems((prev) => {\r\n const newItems = [...prev, payload]\r\n // Save to localStorage if in browser environment\r\n if (isBrowser()) {\r\n localStorage.setItem(CART_STORAGE_KEY, JSON.stringify(newItems))\r\n }\r\n return newItems\r\n })\r\n })\r\n\r\n const unsubRemove = mfeBridge.subscribe(CART_CHANNELS.REMOVE, (payload: { id: number }) => {\r\n setItems((prev) => {\r\n const newItems = prev.filter((item) => item.id !== payload.id)\r\n // Save to localStorage if in browser environment\r\n if (isBrowser()) {\r\n localStorage.setItem(CART_STORAGE_KEY, JSON.stringify(newItems))\r\n }\r\n return newItems\r\n })\r\n })\r\n\r\n const unsubClear = mfeBridge.subscribe(CART_CHANNELS.CLEAR, () => {\r\n setItems([])\r\n if (isBrowser()) {\r\n localStorage.removeItem(CART_STORAGE_KEY)\r\n }\r\n })\r\n\r\n const unsubUpdate = mfeBridge.subscribe(CART_CHANNELS.UPDATE, (payload: ICartItem[]) => {\r\n setItems(payload)\r\n if (isBrowser()) {\r\n localStorage.setItem(CART_STORAGE_KEY, JSON.stringify(payload))\r\n }\r\n })\r\n\r\n // Subscribe to init requests from other microFEs\r\n const unsubInitReq = mfeBridge.subscribe(CART_CHANNELS.INIT_REQUEST, () => {\r\n // If state is already available, return it to other microFEs\r\n if (items.length > 0) {\r\n mfeBridge.publish(CART_CHANNELS.INIT_RESPONSE, items)\r\n }\r\n })\r\n\r\n // Subscribe to init responses if state is not available\r\n const unsubInitRes = mfeBridge.subscribe(CART_CHANNELS.INIT_RESPONSE, (payload: ICartItem[]) => {\r\n if (!initialized.current && payload && payload.length > 0) {\r\n setItems(payload)\r\n if (isBrowser()) {\r\n localStorage.setItem(CART_STORAGE_KEY, JSON.stringify(payload))\r\n }\r\n initialized.current = true\r\n }\r\n })\r\n\r\n // When mounted, send init request (only if no state from localStorage)\r\n if (!initialized.current) {\r\n mfeBridge.publish(CART_CHANNELS.INIT_REQUEST, null)\r\n }\r\n\r\n return () => {\r\n unsubAdd()\r\n unsubRemove()\r\n unsubClear()\r\n unsubUpdate()\r\n unsubInitReq()\r\n unsubInitRes()\r\n }\r\n }, [])\r\n\r\n return { items, totalItems: items.length }\r\n}\r\n\r\n/**\r\n * Hook to provide cart actions\r\n * This hook will:\r\n * - Only perform actions, not manage state\r\n * - Use mfeEventBridge to communicate with other microFEs\r\n * - Provide add, remove, clear, and update actions\r\n */\r\nexport const useCartActions = () => {\r\n // Add item to cart\r\n const addToCart = useCallback((item: ICartItem) => {\r\n mfeBridge.publish(CART_CHANNELS.ADD, item)\r\n }, [])\r\n\r\n // Remove item from cart\r\n const removeFromCart = useCallback((itemId: number) => {\r\n mfeBridge.publish(CART_CHANNELS.REMOVE, { id: itemId })\r\n }, [])\r\n\r\n // Clear cart\r\n const clearCart = useCallback(() => {\r\n mfeBridge.publish(CART_CHANNELS.CLEAR, null)\r\n }, [])\r\n\r\n // Update entire cart\r\n const updateCart = useCallback((items: ICartItem[]) => {\r\n mfeBridge.publish(CART_CHANNELS.UPDATE, items)\r\n }, [])\r\n\r\n return {\r\n addToCart,\r\n removeFromCart,\r\n clearCart,\r\n updateCart\r\n }\r\n}\r\n"],"names":["CART_STORAGE_KEY","CART_CHANNELS","ADD","REMOVE","CLEAR","INIT_REQUEST","INIT_RESPONSE","UPDATE","useCartStore","_useState","useState","_useState2","_slicedToArray","items","setItems","initialized","useRef","useEffect","isBrowser","storedItems","localStorage","getItem","parsedItems","JSON","parse","Array","isArray","current","e","console","error","unsubAdd","mfeBridge","subscribe","payload","log","prev","newItems","concat","_toConsumableArray","setItem","stringify","unsubRemove","filter","item","id","unsubClear","removeItem","unsubUpdate","unsubInitReq","length","publish","unsubInitRes","totalItems","useCartActions","addToCart","useCallback","removeFromCart","itemId","clearCart","updateCart"],"mappings":"sQAaA,IAAMA,EAAmB,iBAGZC,EAAgB,CAE3BC,IAAK,eAELC,OAAQ,kBAERC,MAAO,iBAEPC,aAAc,wBAEdC,cAAe,yBAEfC,OAAQ,mBAwBGC,EAAe,WAC1B,IAAAC,EAA0BC,EAAsB,IAAGC,EAAAC,EAAAH,EAAA,GAA5CI,EAAKF,EAAA,GAAEG,EAAQH,EAAA,GAGhBI,EAAcC,GAAO,GA8F3B,OA5FAC,GAAU,WAER,GAAKC,IAAL,CAKA,IAAMC,EAAcC,aAAaC,QAAQrB,GACzC,GAAImB,EACF,IACE,IAAMG,EAAcC,KAAKC,MAAML,GAC3BM,MAAMC,QAAQJ,KAChBR,EAASQ,GACTP,EAAYY,SAAU,EAEzB,CAAC,MAAOC,GACPC,QAAQC,MAAM,0CAA2CF,EAC1D,CAIH,IAAMG,EAAWC,EAAUC,UAAUhC,EAAcC,KAAK,SAACgC,GACvDL,QAAQM,IAAI,sBAAuBD,GACnCpB,GAAS,SAACsB,GACR,IAAMC,KAAQC,OAAAC,EAAOH,GAAMF,CAAAA,IAK3B,OAHIhB,KACFE,aAAaoB,QAAQxC,EAAkBuB,KAAKkB,UAAUJ,IAEjDA,CACT,GACF,IAEMK,EAAcV,EAAUC,UAAUhC,EAAcE,QAAQ,SAAC+B,GAC7DpB,GAAS,SAACsB,GACR,IAAMC,EAAWD,EAAKO,QAAO,SAACC,GAAI,OAAKA,EAAKC,KAAOX,EAAQW,MAK3D,OAHI3B,KACFE,aAAaoB,QAAQxC,EAAkBuB,KAAKkB,UAAUJ,IAEjDA,CACT,GACF,IAEMS,EAAad,EAAUC,UAAUhC,EAAcG,OAAO,WAC1DU,EAAS,IACLI,KACFE,aAAa2B,WAAW/C,EAE5B,IAEMgD,EAAchB,EAAUC,UAAUhC,EAAcM,QAAQ,SAAC2B,GAC7DpB,EAASoB,GACLhB,KACFE,aAAaoB,QAAQxC,EAAkBuB,KAAKkB,UAAUP,GAE1D,IAGMe,EAAejB,EAAUC,UAAUhC,EAAcI,cAAc,WAE/DQ,EAAMqC,OAAS,GACjBlB,EAAUmB,QAAQlD,EAAcK,cAAeO,EAEnD,IAGMuC,EAAepB,EAAUC,UAAUhC,EAAcK,eAAe,SAAC4B,IAChEnB,EAAYY,SAAWO,GAAWA,EAAQgB,OAAS,IACtDpC,EAASoB,GACLhB,KACFE,aAAaoB,QAAQxC,EAAkBuB,KAAKkB,UAAUP,IAExDnB,EAAYY,SAAU,EAE1B,IAOA,OAJKZ,EAAYY,SACfK,EAAUmB,QAAQlD,EAAcI,aAAc,MAGzC,WACL0B,IACAW,IACAI,IACAE,IACAC,IACAG,GACD,CArFA,CAsFF,GAAE,IAEI,CAAEvC,MAAAA,EAAOwC,WAAYxC,EAAMqC,OACpC,EASaI,EAAiB,WAqB5B,MAAO,CACLC,UApBgBC,GAAY,SAACZ,GAC7BZ,EAAUmB,QAAQlD,EAAcC,IAAK0C,EACtC,GAAE,IAmBDa,eAhBqBD,GAAY,SAACE,GAClC1B,EAAUmB,QAAQlD,EAAcE,OAAQ,CAAE0C,GAAIa,GAC/C,GAAE,IAeDC,UAZgBH,GAAY,WAC5BxB,EAAUmB,QAAQlD,EAAcG,MAAO,KACxC,GAAE,IAWDwD,WARiBJ,GAAY,SAAC3C,GAC9BmB,EAAUmB,QAAQlD,EAAcM,OAAQM,EACzC,GAAE,IAQL"}
1
+ {"version":3,"file":"cart.js","sources":["../../src/mfe-shared/cart.tsx"],"sourcesContent":["/**\r\n * cart.tsx - Shared shopping cart system for micro-frontends\r\n *\r\n * This module provides hooks for managing a shared shopping cart across\r\n * multiple micro-frontends. The cart state is synchronized using the\r\n * mfeBridge communication system and persisted in localStorage.\r\n */\r\n\r\nimport { useEffect, useState, useRef, useCallback, useMemo } from 'react'\r\nimport { mfeBridge } from './mfe-bridge'\r\nimport { isBrowser } from './environment'\r\nimport { ICartItem, CART_CHANNELS } from './cart.types'\r\n\r\n/** LocalStorage key for persisting cart items */\r\nconst CART_STORAGE_KEY = 'mfe_cart_items'\r\n\r\nexport interface IMfeCartStoreConfigs {\r\n storageKey: string\r\n}\r\n\r\n/**\r\n * Hook to manage cart state across microFE\r\n * This hook will:\r\n * - Initialize cart from localStorage\r\n * - Listen for cart events (add, remove, clear, update)\r\n * - Provide current cart state\r\n */\r\nexport function useMfeCartStore<O = any, T extends ICartItem<O> = ICartItem<O>>(configs?: IMfeCartStoreConfigs) {\r\n // Use provided storage key or default to CART_STORAGE_KEY\r\n const cartStorageKey = useMemo(() => configs?.storageKey || CART_STORAGE_KEY, [configs?.storageKey])\r\n\r\n // State to hold cart items\r\n const [items, setItems] = useState<T[]>([])\r\n\r\n // Mark as initialized\r\n const initialized = useRef(false)\r\n\r\n useEffect(() => {\r\n // Skip localStorage operations in non-browser environments\r\n if (!isBrowser()) {\r\n return\r\n }\r\n\r\n // Restore from localStorage if available\r\n const storedItems = localStorage.getItem(cartStorageKey)\r\n if (storedItems) {\r\n try {\r\n const parsedItems = JSON.parse(storedItems)\r\n if (Array.isArray(parsedItems)) {\r\n setItems(parsedItems)\r\n initialized.current = true\r\n }\r\n } catch (e) {\r\n console.error('Failed to parse cart from localStorage:', e)\r\n }\r\n }\r\n\r\n // Subscribe to cart events\r\n const unsubAdd = mfeBridge.subscribe(CART_CHANNELS.ADD, (payload: T) => {\r\n setItems((prev) => {\r\n const newItems = [...prev, payload]\r\n if (JSON.stringify(newItems) !== JSON.stringify(prev)) {\r\n // Save to localStorage only if value changed\r\n if (isBrowser()) {\r\n const current = localStorage.getItem(cartStorageKey)\r\n if (JSON.stringify(newItems) !== current) {\r\n localStorage.setItem(cartStorageKey, JSON.stringify(newItems))\r\n }\r\n }\r\n return newItems\r\n }\r\n return prev\r\n })\r\n })\r\n\r\n const unsubRemove = mfeBridge.subscribe(CART_CHANNELS.REMOVE, (payload: { id: string }) => {\r\n setItems((prev) => {\r\n const newItems = prev.filter((item) => item.ProductId !== payload.id)\r\n if (JSON.stringify(newItems) !== JSON.stringify(prev)) {\r\n // Save to localStorage only if value changed\r\n if (isBrowser()) {\r\n const current = localStorage.getItem(cartStorageKey)\r\n if (JSON.stringify(newItems) !== current) {\r\n localStorage.setItem(cartStorageKey, JSON.stringify(newItems))\r\n }\r\n }\r\n return newItems\r\n }\r\n return prev\r\n })\r\n })\r\n\r\n const unsubClear = mfeBridge.subscribe(CART_CHANNELS.CLEAR, () => {\r\n setItems([])\r\n if (isBrowser()) {\r\n localStorage.removeItem(cartStorageKey)\r\n }\r\n })\r\n\r\n const unsubUpdate = mfeBridge.subscribe(CART_CHANNELS.UPDATE, (payload: T[]) => {\r\n setItems((prev) => {\r\n if (JSON.stringify(payload) !== JSON.stringify(prev)) {\r\n // Save to localStorage only if value changed\r\n if (isBrowser()) {\r\n const current = localStorage.getItem(cartStorageKey)\r\n if (JSON.stringify(payload) !== current) {\r\n localStorage.setItem(cartStorageKey, JSON.stringify(payload))\r\n }\r\n }\r\n return payload\r\n }\r\n return prev\r\n })\r\n })\r\n\r\n // Subscribe to init requests from other microFEs\r\n const unsubInitReq = mfeBridge.subscribe(CART_CHANNELS.INIT_REQUEST, () => {\r\n // If state is already available, return it to other microFEs\r\n if (items.length > 0) {\r\n mfeBridge.publish(CART_CHANNELS.INIT_RESPONSE, items)\r\n }\r\n })\r\n\r\n // Subscribe to init responses if state is not available\r\n const unsubInitRes = mfeBridge.subscribe(CART_CHANNELS.INIT_RESPONSE, (payload: T[]) => {\r\n if (!initialized.current && payload && payload.length > 0) {\r\n setItems(payload)\r\n if (isBrowser()) {\r\n localStorage.setItem(cartStorageKey, JSON.stringify(payload))\r\n }\r\n initialized.current = true\r\n }\r\n })\r\n\r\n // When mounted, send init request (only if no state from localStorage)\r\n if (!initialized.current) {\r\n mfeBridge.publish(CART_CHANNELS.INIT_REQUEST, null)\r\n }\r\n\r\n return () => {\r\n unsubAdd()\r\n unsubRemove()\r\n unsubClear()\r\n unsubUpdate()\r\n unsubInitReq()\r\n unsubInitRes()\r\n }\r\n }, [])\r\n\r\n return { items, totalItems: items.length }\r\n}\r\n\r\n/**\r\n * Hook to provide cart actions\r\n * This hook will:\r\n * - Only perform actions, not manage state\r\n * - Use mfeEventBridge to communicate with other microFEs\r\n * - Provide add, remove, clear, and update actions\r\n */\r\nexport function useMfeCartActions<O = any, T extends ICartItem<O> = ICartItem<O>>() {\r\n // Add item to cart\r\n const addToCart = useCallback((item: T) => {\r\n mfeBridge.publish(CART_CHANNELS.ADD, item)\r\n }, [])\r\n\r\n // Remove item from cart\r\n const removeFromCart = useCallback((productId: string) => {\r\n mfeBridge.publish(CART_CHANNELS.REMOVE, { id: productId })\r\n }, [])\r\n\r\n // Clear cart\r\n const clearCart = useCallback(() => {\r\n mfeBridge.publish(CART_CHANNELS.CLEAR, null)\r\n }, [])\r\n\r\n // Update entire cart\r\n const updateCart = useCallback((items: T[]) => {\r\n mfeBridge.publish(CART_CHANNELS.UPDATE, items)\r\n }, [])\r\n\r\n return {\r\n addToCart,\r\n removeFromCart,\r\n clearCart,\r\n updateCart\r\n }\r\n}\r\n"],"names":["useMfeCartStore","configs","cartStorageKey","useMemo","storageKey","_useState","useState","_useState2","_slicedToArray","items","setItems","initialized","useRef","useEffect","isBrowser","storedItems","localStorage","getItem","parsedItems","JSON","parse","Array","isArray","current","e","console","error","unsubAdd","mfeBridge","subscribe","CART_CHANNELS","ADD","payload","prev","newItems","concat","_toConsumableArray","stringify","setItem","unsubRemove","REMOVE","filter","item","ProductId","id","unsubClear","CLEAR","removeItem","unsubUpdate","UPDATE","unsubInitReq","INIT_REQUEST","length","publish","INIT_RESPONSE","unsubInitRes","totalItems","useMfeCartActions","addToCart","useCallback","removeFromCart","productId","clearCart","updateCart"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{slicedToArray as r}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsx as t,Fragment as e}from"react/jsx-runtime";import{useState as a,useEffect as i}from"react";import{useCartStore as o,useCartActions as l}from"./cart.js";import{HydrationGuard as m}from"./hydration-helper.js";var n=function(n){var c=n.children,p=n.initialCartItems,s=void 0===p?[]:p;n.hydrateFromStorage,o().items;var d=l().updateCart,h=a(!1),u=r(h,2),f=u[0],v=u[1];return i((function(){!f&&s.length>0&&(d(s),v(!0))}),[f,s,d]),t(m,{serverFallback:t(e,{children:c}),hydrationDelay:100,children:c})};export{n as SsrCartProvider};
1
+ import{slicedToArray as r}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsx as t,Fragment as e}from"react/jsx-runtime";import{useState as a,useEffect as i}from"react";import{useMfeCartStore as o,useMfeCartActions as l}from"./cart.js";import{HydrationGuard as m}from"./hydration-helper.js";var n=function(n){var c=n.children,p=n.initialCartItems,s=void 0===p?[]:p;n.hydrateFromStorage,o().items;var d=l().updateCart,h=a(!1),u=r(h,2),f=u[0],v=u[1];return i((function(){!f&&s.length>0&&(d(s),v(!0))}),[f,s,d]),t(m,{serverFallback:t(e,{children:c}),hydrationDelay:100,children:c})};export{n as SsrCartProvider};
2
2
  //# sourceMappingURL=cart.ssr.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cart.ssr.js","sources":["../../src/mfe-shared/cart.ssr.tsx"],"sourcesContent":["import React, { useState, useEffect } from 'react'\r\nimport { ICartItem, useCartActions, useCartStore } from './cart'\r\nimport { HydrationGuard } from './hydration-helper'\r\n\r\n/**\r\n * Props for the SSR-compatible cart provider\r\n */\r\ninterface ISsrCartProviderProps {\r\n /** Content to render */\r\n children: React.ReactNode\r\n /** Initial cart items for SSR */\r\n initialCartItems?: ICartItem[]\r\n /** Should hydrate cart from browser storage after rendering */\r\n hydrateFromStorage?: boolean\r\n}\r\n\r\n/**\r\n * Cart provider component that supports SSR\r\n * \r\n * This component allows providing initial cart data during server-side rendering\r\n * and then hydrating from localStorage or other storage once client-side.\r\n */\r\nexport const SsrCartProvider: React.FC<ISsrCartProviderProps> = ({\r\n children,\r\n initialCartItems = [],\r\n hydrateFromStorage = true\r\n}) => {\r\n const { items } = useCartStore()\r\n const { updateCart } = useCartActions()\r\n const [isInitialized, setIsInitialized] = useState(false)\r\n\r\n // Initialize cart with provided items on first render\r\n useEffect(() => {\r\n if (!isInitialized && initialCartItems.length > 0) {\r\n updateCart(initialCartItems)\r\n setIsInitialized(true)\r\n }\r\n }, [isInitialized, initialCartItems, updateCart])\r\n\r\n return (\r\n <HydrationGuard\r\n serverFallback={<>{children}</>}\r\n hydrationDelay={100}\r\n >\r\n {children}\r\n </HydrationGuard>\r\n )\r\n}\r\n\r\n/**\r\n * CartItemsComponent - SSR-aware cart items display component\r\n */\r\ninterface ICartItemsComponentProps {\r\n /** Function to render each cart item */\r\n renderItem: (item: ICartItem) => React.ReactNode\r\n /** Optional empty cart placeholder */\r\n emptyCart?: React.ReactNode\r\n /** Initial cart items for SSR */\r\n initialCartItems?: ICartItem[]\r\n}\r\n\r\n/**\r\n * SSR-compatible cart items component\r\n * \r\n * This component handles both server-side rendering with initial data\r\n * and client-side hydration from the cart store.\r\n */\r\nexport const CartItemsComponent: React.FC<ICartItemsComponentProps> = ({\r\n renderItem,\r\n emptyCart,\r\n initialCartItems = []\r\n}) => {\r\n const { items } = useCartStore()\r\n\r\n return (\r\n <HydrationGuard\r\n serverFallback={\r\n <>\r\n {initialCartItems.length === 0 && emptyCart}\r\n {initialCartItems.map(renderItem)}\r\n </>\r\n }\r\n >\r\n {items.length === 0 && emptyCart}\r\n {items.map(renderItem)}\r\n </HydrationGuard>\r\n )\r\n}\r\n"],"names":["SsrCartProvider","_ref","children","_ref$initialCartItems","initialCartItems","hydrateFromStorage","useCartStore","items","updateCart","useCartActions","_useState","useState","_useState2","_slicedToArray","isInitialized","setIsInitialized","useEffect","length","_jsx","HydrationGuard","serverFallback","_Fragment","hydrationDelay"],"mappings":"uSAsBaA,EAAmD,SAApCC,GAIvB,IAHHC,EAAQD,EAARC,SAAQC,EAAAF,EACRG,iBAAAA,OAAmB,IAAHD,EAAG,GAAEA,EAAAF,EACrBI,mBAEkBC,IAAVC,MACR,IAAQC,EAAeC,IAAfD,WACRE,EAA0CC,GAAS,GAAMC,EAAAC,EAAAH,EAAA,GAAlDI,EAAaF,EAAA,GAAEG,EAAgBH,EAAA,GAUtC,OAPAI,GAAU,YACHF,GAAiBV,EAAiBa,OAAS,IAC9CT,EAAWJ,GACXW,GAAiB,GAEpB,GAAE,CAACD,EAAeV,EAAkBI,IAGnCU,EAACC,EACC,CAAAC,eAAgBF,EAAGG,EAAA,CAAAnB,SAAAA,IACnBoB,eAAgB,aAEfpB,GAGP"}
1
+ {"version":3,"file":"cart.ssr.js","sources":["../../src/mfe-shared/cart.ssr.tsx"],"sourcesContent":["import React, { useState, useEffect } from 'react'\r\nimport { ICartItem, useMfeCartActions, useMfeCartStore } from './cart'\r\nimport { HydrationGuard } from './hydration-helper'\r\n\r\n/**\r\n * Props for the SSR-compatible cart provider\r\n */\r\ninterface ISsrCartProviderProps {\r\n /** Content to render */\r\n children: React.ReactNode\r\n /** Initial cart items for SSR */\r\n initialCartItems?: ICartItem[]\r\n /** Should hydrate cart from browser storage after rendering */\r\n hydrateFromStorage?: boolean\r\n}\r\n\r\n/**\r\n * Cart provider component that supports SSR\r\n * \r\n * This component allows providing initial cart data during server-side rendering\r\n * and then hydrating from localStorage or other storage once client-side.\r\n */\r\nexport const SsrCartProvider: React.FC<ISsrCartProviderProps> = ({\r\n children,\r\n initialCartItems = [],\r\n hydrateFromStorage = true\r\n}) => {\r\n const { items } = useMfeCartStore()\r\n const { updateCart } = useMfeCartActions()\r\n const [isInitialized, setIsInitialized] = useState(false)\r\n\r\n // Initialize cart with provided items on first render\r\n useEffect(() => {\r\n if (!isInitialized && initialCartItems.length > 0) {\r\n updateCart(initialCartItems)\r\n setIsInitialized(true)\r\n }\r\n }, [isInitialized, initialCartItems, updateCart])\r\n\r\n return (\r\n <HydrationGuard\r\n serverFallback={<>{children}</>}\r\n hydrationDelay={100}\r\n >\r\n {children}\r\n </HydrationGuard>\r\n )\r\n}\r\n\r\n/**\r\n * CartItemsComponent - SSR-aware cart items display component\r\n */\r\ninterface ICartItemsComponentProps {\r\n /** Function to render each cart item */\r\n renderItem: (item: ICartItem) => React.ReactNode\r\n /** Optional empty cart placeholder */\r\n emptyCart?: React.ReactNode\r\n /** Initial cart items for SSR */\r\n initialCartItems?: ICartItem[]\r\n}\r\n\r\n/**\r\n * SSR-compatible cart items component\r\n * \r\n * This component handles both server-side rendering with initial data\r\n * and client-side hydration from the cart store.\r\n */\r\nexport const CartItemsComponent: React.FC<ICartItemsComponentProps> = ({\r\n renderItem,\r\n emptyCart,\r\n initialCartItems = []\r\n}) => {\r\n const { items } = useMfeCartStore()\r\n\r\n return (\r\n <HydrationGuard\r\n serverFallback={\r\n <>\r\n {initialCartItems.length === 0 && emptyCart}\r\n {initialCartItems.map(renderItem)}\r\n </>\r\n }\r\n >\r\n {items.length === 0 && emptyCart}\r\n {items.map(renderItem)}\r\n </HydrationGuard>\r\n )\r\n}\r\n"],"names":["SsrCartProvider","_ref","children","_ref$initialCartItems","initialCartItems","hydrateFromStorage","useMfeCartStore","items","updateCart","useMfeCartActions","_useState","useState","_useState2","_slicedToArray","isInitialized","setIsInitialized","useEffect","length","_jsx","HydrationGuard","serverFallback","_Fragment","hydrationDelay"],"mappings":"6SAsBaA,EAAmD,SAApCC,GAIvB,IAHHC,EAAQD,EAARC,SAAQC,EAAAF,EACRG,iBAAAA,OAAmB,IAAHD,EAAG,GAAEA,EAAAF,EACrBI,mBAEkBC,IAAVC,MACR,IAAQC,EAAeC,IAAfD,WACRE,EAA0CC,GAAS,GAAMC,EAAAC,EAAAH,EAAA,GAAlDI,EAAaF,EAAA,GAAEG,EAAgBH,EAAA,GAUtC,OAPAI,GAAU,YACHF,GAAiBV,EAAiBa,OAAS,IAC9CT,EAAWJ,GACXW,GAAiB,GAEpB,GAAE,CAACD,EAAeV,EAAkBI,IAGnCU,EAACC,EACC,CAAAC,eAAgBF,EAAGG,EAAA,CAAAnB,SAAAA,IACnBoB,eAAgB,aAEfpB,GAGP"}
@@ -0,0 +1,2 @@
1
+ var e={ADD:"mfe:cart:add",REMOVE:"mfe:cart:remove",CLEAR:"mfe:cart:clear",INIT_REQUEST:"mfe:cart:init_request",INIT_RESPONSE:"mfe:cart:init_response",UPDATE:"mfe:cart:update"};export{e as CART_CHANNELS};
2
+ //# sourceMappingURL=cart.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cart.types.js","sources":["../../src/mfe-shared/cart.types.ts"],"sourcesContent":["/**\r\n * cart.types.ts - Type definitions for the shopping cart system\r\n */\r\n\r\nexport type CartItemType = 'Media' | 'Audio'\r\n\r\n/**\r\n * Shopping cart item structure\r\n */\r\nexport interface ICartItem<O = any> {\r\n ProductId: string\r\n PricePackageId: string\r\n Amount: number\r\n SocialUrl?: string\r\n Type?: CartItemType\r\n ProductName?: string\r\n Options?: O\r\n}\r\n\r\n/** Communication channels for cart operations */\r\nexport const CART_CHANNELS = {\r\n /** Add an item to the cart */\r\n ADD: 'mfe:cart:add',\r\n /** Remove an item from the cart */\r\n REMOVE: 'mfe:cart:remove',\r\n /** Clear all items from the cart */\r\n CLEAR: 'mfe:cart:clear',\r\n /** Request initial cart data (when a new MFE loads) */\r\n INIT_REQUEST: 'mfe:cart:init_request',\r\n /** Response with cart data (to initialize a new MFE) */\r\n INIT_RESPONSE: 'mfe:cart:init_response',\r\n /** Update the entire cart at once */\r\n UPDATE: 'mfe:cart:update'\r\n} as const\r\n"],"names":["CART_CHANNELS","ADD","REMOVE","CLEAR","INIT_REQUEST","INIT_RESPONSE","UPDATE"],"mappings":"AAoBO,IAAMA,EAAgB,CAE3BC,IAAK,eAELC,OAAQ,kBAERC,MAAO,iBAEPC,aAAc,wBAEdC,cAAe,yBAEfC,OAAQ"}
@@ -1,2 +1,2 @@
1
- export{mfeBridge}from"./mfe-bridge.js";export{AuthProvider,useAuth}from"./auth.js";export{AUTH_CHANNELS}from"./auth.types.js";export{SsrAuthProvider}from"./auth.ssr.js";export{CART_CHANNELS,useCartActions,useCartStore}from"./cart.js";export{SsrCartProvider}from"./cart.ssr.js";export{MfeLink,MfeNavigateReactProvider,NAVIGATION_CHANNELS,useMfeNavigate}from"./navigation.js";export{isBrowser}from"./environment.js";export{HydrationGuard,useHydration}from"./hydration-helper.js";
1
+ export{mfeBridge}from"./mfe-bridge.js";export{MfeAuthProvider,useMfeAuth}from"./auth.js";export{AUTH_CHANNELS}from"./auth.types.js";export{SsrAuthProvider}from"./auth.ssr.js";export{useMfeCartActions,useMfeCartStore}from"./cart.js";export{CART_CHANNELS}from"./cart.types.js";export{SsrCartProvider}from"./cart.ssr.js";export{MfeLink,MfeNavigateProvider,NAVIGATION_CHANNELS,useMfeNavigate}from"./navigation.js";export{isBrowser}from"./environment.js";export{HydrationGuard,useHydration}from"./hydration-helper.js";export{MfeAuthDebugPanel}from"./auth.debug.js";export{MfeCartDebugPanel}from"./cart.debug.js";export{MfeNavigateDebugPanel}from"./navigation.debug.js";
2
2
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,2 @@
1
+ import{slicedToArray as e,objectSpread2 as r,toConsumableArray as n}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsxs as t,jsx as i}from"react/jsx-runtime";import{useState as o,useEffect as a}from"react";var l=function(l){var s=l.style,c=o([]),d=e(c,2),f=d[0],m=d[1];return a((function(){var e=function(e){var r=e.detail,t=r.primaryHref,i=r.secondaryHref,o=r.internal,a=r.options;m((function(e){return[{primaryHref:t,secondaryHref:i,internal:o,options:a}].concat(n(e.slice(0,9)))}))};return globalThis.addEventListener("mfe:navigate",e),function(){return globalThis.removeEventListener("mfe:navigate",e)}}),[]),t("div",{style:r({position:"fixed",background:"rgba(0,0,0,0.8)",color:"#fff",padding:12,borderRadius:8,fontSize:12,zIndex:9999,maxWidth:320,maxHeight:240,overflowY:"auto",boxShadow:"0 2px 8px rgba(0,0,0,0.2)"},null!=s?s:{bottom:16,left:16}),children:[i("div",{style:{fontWeight:"bold",marginBottom:8},children:"MFE Navigate Debug"}),0===f.length?i("div",{style:{opacity:.7},children:"No navigation events"}):i("ul",{style:{margin:0,padding:0,listStyle:"none"},children:f.map((function(e,r){var n;return t("li",{style:{marginBottom:4},children:[i("span",{style:{color:"#90ee90"},children:e.primaryHref}),e.secondaryHref&&t("span",{style:{color:"#ffa500",marginLeft:8},children:["→ ",e.secondaryHref]}),e.internal&&i("span",{style:{color:"#87ceeb",marginLeft:8},children:"[internal]"}),(null===(n=e.options)||void 0===n?void 0:n.target)&&t("span",{style:{color:"#ffb6c1",marginLeft:8},children:["(",e.options.target,")"]})]},r)}))})]})};export{l as MfeNavigateDebugPanel};
2
+ //# sourceMappingURL=navigation.debug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.debug.js","sources":["../../src/mfe-shared/navigation.debug.tsx"],"sourcesContent":["import { useEffect, useState } from 'react'\r\nimport type { FC } from 'react'\r\nimport type { IMfeNavigate } from './navigation'\r\n\r\nconst MAX_EVENTS = 10\r\n\r\nexport const MfeNavigateDebugPanel: FC<{ style?: React.CSSProperties }> = ({ style }) => {\r\n const [debugEvents, setDebugEvents] = useState<IMfeNavigate[]>([])\r\n\r\n useEffect(() => {\r\n const handleNavigate = (e: CustomEvent) => {\r\n const { primaryHref, secondaryHref, internal, options } = e.detail as IMfeNavigate\r\n setDebugEvents((events) => [{ primaryHref, secondaryHref, internal, options }, ...events.slice(0, MAX_EVENTS - 1)])\r\n }\r\n globalThis.addEventListener('mfe:navigate', handleNavigate as EventListener)\r\n return () => globalThis.removeEventListener('mfe:navigate', handleNavigate as EventListener)\r\n }, [])\r\n\r\n return (\r\n <div\r\n style={{\r\n position: 'fixed',\r\n background: 'rgba(0,0,0,0.8)',\r\n color: '#fff',\r\n padding: 12,\r\n borderRadius: 8,\r\n fontSize: 12,\r\n zIndex: 9999,\r\n maxWidth: 320,\r\n maxHeight: 240,\r\n overflowY: 'auto',\r\n boxShadow: '0 2px 8px rgba(0,0,0,0.2)',\r\n ...(style ?? { bottom: 16, left: 16 })\r\n }}\r\n >\r\n <div style={{ fontWeight: 'bold', marginBottom: 8 }}>MFE Navigate Debug</div>\r\n {debugEvents.length === 0 ? (\r\n <div style={{ opacity: 0.7 }}>No navigation events</div>\r\n ) : (\r\n <ul style={{ margin: 0, padding: 0, listStyle: 'none' }}>\r\n {debugEvents.map((ev, idx) => (\r\n <li key={idx} style={{ marginBottom: 4 }}>\r\n <span style={{ color: '#90ee90' }}>{ev.primaryHref}</span>\r\n {ev.secondaryHref && <span style={{ color: '#ffa500', marginLeft: 8 }}>→ {ev.secondaryHref}</span>}\r\n {ev.internal && <span style={{ color: '#87ceeb', marginLeft: 8 }}>[internal]</span>}\r\n {ev.options?.target && <span style={{ color: '#ffb6c1', marginLeft: 8 }}>({ev.options.target})</span>}\r\n </li>\r\n ))}\r\n </ul>\r\n )}\r\n </div>\r\n )\r\n}\r\n"],"names":["MfeNavigateDebugPanel","_ref","style","_useState","useState","_useState2","_slicedToArray","debugEvents","setDebugEvents","useEffect","handleNavigate","e","_e$detail","detail","primaryHref","secondaryHref","internal","options","events","concat","_toConsumableArray","slice","MAX_EVENTS","globalThis","addEventListener","removeEventListener","_jsxs","_objectSpread","position","background","color","padding","borderRadius","fontSize","zIndex","maxWidth","maxHeight","overflowY","boxShadow","bottom","left","children","_jsx","fontWeight","marginBottom","length","opacity","margin","listStyle","map","ev","idx","_ev$options","marginLeft","target"],"mappings":"qNAIA,IAEaA,EAA6D,SAAxCC,GAAsD,IAAXC,EAAKD,EAALC,MAC3EC,EAAsCC,EAAyB,IAAGC,EAAAC,EAAAH,EAAA,GAA3DI,EAAWF,EAAA,GAAEG,EAAcH,EAAA,GAWlC,OATAI,GAAU,WACR,IAAMC,EAAiB,SAACC,GACtB,IAAAC,EAA0DD,EAAEE,OAApDC,EAAWF,EAAXE,YAAaC,EAAaH,EAAbG,cAAeC,EAAQJ,EAARI,SAAUC,EAAOL,EAAPK,QAC9CT,GAAe,SAACU,GAAM,MAAM,CAAA,CAAEJ,YAAAA,EAAaC,cAAAA,EAAeC,SAAAA,EAAUC,QAAAA,IAASE,OAAAC,EAAKF,EAAOG,MAAM,EAAGC,IAAe,GAClH,EAED,OADAC,WAAWC,iBAAiB,eAAgBd,GACrC,WAAA,OAAMa,WAAWE,oBAAoB,eAAgBf,EAAgC,CAC7F,GAAE,IAGDgB,EACE,MAAA,CAAAxB,MAAKyB,EAAA,CACHC,SAAU,QACVC,WAAY,kBACZC,MAAO,OACPC,QAAS,GACTC,aAAc,EACdC,SAAU,GACVC,OAAQ,KACRC,SAAU,IACVC,UAAW,IACXC,UAAW,OACXC,UAAW,6BACPpC,QAAAA,EAAS,CAAEqC,OAAQ,GAAIC,KAAM,KAClCC,SAAA,CAEDC,SAAKxC,MAAO,CAAEyC,WAAY,OAAQC,aAAc,GAAGH,SAAA,uBAC3B,IAAvBlC,EAAYsC,OACXH,EAAK,MAAA,CAAAxC,MAAO,CAAE4C,QAAS,IAAiCL,SAAA,yBAExDC,EAAI,KAAA,CAAAxC,MAAO,CAAE6C,OAAQ,EAAGhB,QAAS,EAAGiB,UAAW,QAAQP,SACpDlC,EAAY0C,KAAI,SAACC,EAAIC,GAAG,IAAAC,EAAA,OACvB1B,EAAA,KAAA,CAAcxB,MAAO,CAAE0C,aAAc,GAAGH,SAAA,CACtCC,UAAMxC,MAAO,CAAE4B,MAAO,oBAAcoB,EAAGpC,cACtCoC,EAAGnC,eAAiBW,UAAMxB,MAAO,CAAE4B,MAAO,UAAWuB,WAAY,GAAQZ,SAAA,CAAA,KAAAS,EAAGnC,iBAC5EmC,EAAGlC,UAAY0B,EAAM,OAAA,CAAAxC,MAAO,CAAE4B,MAAO,UAAWuB,WAAY,GAAGZ,SAAA,gBACrD,QAAVW,EAAAF,EAAGjC,eAAO,IAAAmC,OAAA,EAAVA,EAAYE,SAAU5B,UAAMxB,MAAO,CAAE4B,MAAO,UAAWuB,WAAY,GAAOZ,SAAA,CAAA,IAAAS,EAAGjC,QAAQqC,OAAM,SAJrFH,EAMV,QAKX"}
@@ -1,2 +1,2 @@
1
- import{objectWithoutProperties as r,objectSpread2 as n}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsx as e,Fragment as t}from"react/jsx-runtime";import{useEffect as i}from"react";import{mfeBridge as a}from"./mfe-bridge.js";import{isBrowser as o}from"./environment.js";var f=["internal","primaryHref","secondaryHref","onClick"],u={NAVIGATE:"mfe:navigation:navigate"},c=function(){return{navigate:function(r){a.publish(u.NAVIGATE,r)}}},l=function(t){var i=t.internal,a=t.primaryHref,o=t.secondaryHref,u=t.onClick,l=r(t,f),m=c().navigate;return e("a",n(n({},l),{},{href:a,onClick:function(r){if(u&&u(r),!r.defaultPrevented)return i&&o?(r.preventDefault(),void m({primaryHref:a,secondaryHref:o,internal:i})):void 0}}))},m=function(r){var n=r.navigate;return i((function(){var r=a.subscribe(u.NAVIGATE,(function(r){var e=r.primaryHref,t=r.secondaryHref,i=r.options;if(e){var a=t||e||"/";"_blank"!==(null==i?void 0:i.target)?n(a,i):o()&&window.open("".concat(a),"_blank")}}));return function(){return r()}}),[n]),e(t,{})};export{l as MfeLink,m as MfeNavigateReactProvider,u as NAVIGATION_CHANNELS,c as useMfeNavigate};
1
+ import{objectWithoutProperties as r,objectSpread2 as n}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsx as e,Fragment as t}from"react/jsx-runtime";import{useEffect as i}from"react";import{mfeBridge as a}from"./mfe-bridge.js";import{isBrowser as o}from"./environment.js";var f=["internal","primaryHref","secondaryHref","onClick"],u={NAVIGATE:"mfe:navigation:navigate"},c=function(){return{navigate:function(r){a.publish(u.NAVIGATE,r)}}},l=function(t){var i=t.internal,a=t.primaryHref,o=t.secondaryHref,u=t.onClick,l=r(t,f),m=c().navigate;return e("a",n(n({},l),{},{href:a,onClick:function(r){if(u&&u(r),!r.defaultPrevented)return i&&o?(r.preventDefault(),void m({primaryHref:a,secondaryHref:o,internal:i})):void 0}}))},m=function(r){var n=r.navigate;return i((function(){var r=a.subscribe(u.NAVIGATE,(function(r){var e=r.primaryHref,t=r.secondaryHref,i=r.options;if(e){var a=t||e||"/";"_blank"!==(null==i?void 0:i.target)?n(a,i):o()&&window.open("".concat(a),"_blank")}}));return function(){return r()}}),[n]),e(t,{})};export{l as MfeLink,m as MfeNavigateProvider,u as NAVIGATION_CHANNELS,c as useMfeNavigate};
2
2
  //# sourceMappingURL=navigation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.js","sources":["../../src/mfe-shared/navigation.tsx"],"sourcesContent":["import { useEffect, type AnchorHTMLAttributes, type FC } from 'react'\r\nimport { mfeBridge } from './mfe-bridge'\r\nimport { isBrowser } from './environment'\r\n\r\n// Define channels for navigation events\r\nexport const NAVIGATION_CHANNELS = {\r\n NAVIGATE: 'mfe:navigation:navigate'\r\n}\r\n\r\nexport type AppSite = 'client' | 'home' | 'music'\r\n\r\nexport type IMfeNavigateHref = {\r\n primaryHref: string\r\n secondaryHref?: string\r\n}\r\n\r\nexport interface IMfeNavigate {\r\n primaryHref: string\r\n secondaryHref?: string\r\n internal?: boolean\r\n site?: AppSite\r\n options?: any\r\n target?: '_self' | '_blank'\r\n}\r\n\r\nexport /**\r\n * Hook for navigation between micro-frontends\r\n * @returns Navigation utilities\r\n */\r\nconst useMfeNavigate = () => {\r\n const navigate = (params: IMfeNavigate) => {\r\n // Use mfeBridge consistently instead of direct globalThis.dispatchEvent\r\n mfeBridge.publish(NAVIGATION_CHANNELS.NAVIGATE, params)\r\n }\r\n return { navigate }\r\n}\r\n\r\nexport interface IMfeLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {\r\n internal?: boolean\r\n primaryHref: string\r\n secondaryHref?: string\r\n}\r\n\r\nexport const MfeLink: FC<IMfeLinkProps> = (props) => {\r\n const { internal, primaryHref, secondaryHref, onClick, ...rest } = props\r\n const { navigate } = useMfeNavigate()\r\n\r\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\r\n if (onClick) onClick(e)\r\n if (e.defaultPrevented) return\r\n if (internal && secondaryHref) {\r\n e.preventDefault()\r\n navigate({ primaryHref, secondaryHref, internal })\r\n return\r\n }\r\n // If not internal or no secondaryHref, let the anchor tag handle it\r\n }\r\n\r\n return <a {...rest} href={primaryHref} onClick={handleClick} />\r\n}\r\n\r\n// Define types to avoid direct imports\r\nexport type NavigateFunction<O = any> = (path: string, options?: O) => void\r\n\r\nexport interface IMfeNavigateReactProviderProps {\r\n navigate: NavigateFunction\r\n}\r\n\r\nexport const MfeNavigateReactProvider: FC<IMfeNavigateReactProviderProps> = ({ navigate }) => {\r\n useEffect(() => {\r\n const unsubscribe = mfeBridge.subscribe(NAVIGATION_CHANNELS.NAVIGATE, (payload: IMfeNavigate) => {\r\n const { primaryHref, secondaryHref, options } = payload\r\n if (!primaryHref) return\r\n // Navigate to secondaryHref if available, otherwise fallback to primaryHref\r\n const url = secondaryHref || primaryHref || '/'\r\n if (options?.target === '_blank') {\r\n // Only open in new window if in browser environment\r\n if (isBrowser()) {\r\n window.open(`${url}`, '_blank')\r\n }\r\n return\r\n }\r\n navigate(url, options)\r\n })\r\n return () => unsubscribe() // Unsubscribe from the event\r\n }, [navigate])\r\n return <></>\r\n}\r\n"],"names":["NAVIGATION_CHANNELS","NAVIGATE","useMfeNavigate","navigate","params","mfeBridge","publish","MfeLink","props","internal","primaryHref","secondaryHref","onClick","rest","_objectWithoutProperties","_excluded","_jsx","_objectSpread","href","e","defaultPrevented","preventDefault","MfeNavigateReactProvider","_ref","useEffect","unsubscribe","subscribe","payload","options","url","target","isBrowser","window","open","concat"],"mappings":"kVAKaA,EAAsB,CACjCC,SAAU,2BAuBNC,EAAiB,WAKrB,MAAO,CAAEC,SAJQ,SAACC,GAEhBC,EAAUC,QAAQN,EAAoBC,SAAUG,EACjD,EAEH,EAQaG,EAA6B,SAACC,GACzC,IAAQC,EAA2DD,EAA3DC,SAAUC,EAAiDF,EAAjDE,YAAaC,EAAoCH,EAApCG,cAAeC,EAAqBJ,EAArBI,QAAYC,EAAIC,EAAKN,EAAKO,GAChEZ,EAAaD,IAAbC,SAaR,OAAOa,EAAA,IAAAC,EAAAA,KAAOJ,GAAI,GAAA,CAAEK,KAAMR,EAAaE,QAXnB,SAACO,GAEnB,GADIP,GAASA,EAAQO,IACjBA,EAAEC,iBACN,OAAIX,GAAYE,GACdQ,EAAEE,sBACFlB,EAAS,CAAEO,YAAAA,EAAaC,cAAAA,EAAeF,SAAAA,UAFzC,CAMD,IAGH,EASaa,EAA+D,SAAvCC,GAAwD,IAAdpB,EAAQoB,EAARpB,SAkB7E,OAjBAqB,GAAU,WACR,IAAMC,EAAcpB,EAAUqB,UAAU1B,EAAoBC,UAAU,SAAC0B,GACrE,IAAQjB,EAAwCiB,EAAxCjB,YAAaC,EAA2BgB,EAA3BhB,cAAeiB,EAAYD,EAAZC,QACpC,GAAKlB,EAAL,CAEA,IAAMmB,EAAMlB,GAAiBD,GAAe,IACpB,YAApBkB,aAAO,EAAPA,EAASE,QAOb3B,EAAS0B,EAAKD,GALRG,KACFC,OAAOC,KAAIC,GAAAA,OAAIL,GAAO,SANR,CAWpB,IACA,OAAO,WAAA,OAAMJ,GAAa,CAC5B,GAAG,CAACtB,IACGa,OACT"}
1
+ {"version":3,"file":"navigation.js","sources":["../../src/mfe-shared/navigation.tsx"],"sourcesContent":["import { useEffect, type AnchorHTMLAttributes, type FC } from 'react'\r\nimport { mfeBridge } from './mfe-bridge'\r\nimport { isBrowser } from './environment'\r\n\r\n// Define channels for navigation events\r\nexport const NAVIGATION_CHANNELS = {\r\n NAVIGATE: 'mfe:navigation:navigate'\r\n}\r\n\r\nexport type AppSite = 'client' | 'home' | 'music'\r\n\r\nexport type IMfeNavigateHref = {\r\n primaryHref: string\r\n secondaryHref?: string\r\n}\r\n\r\nexport interface IMfeNavigate {\r\n primaryHref: string\r\n secondaryHref?: string\r\n internal?: boolean\r\n site?: AppSite\r\n options?: any\r\n target?: '_self' | '_blank'\r\n}\r\n\r\nexport /**\r\n * Hook for navigation between micro-frontends\r\n * @returns Navigation utilities\r\n */\r\nconst useMfeNavigate = () => {\r\n const navigate = (params: IMfeNavigate) => {\r\n // Use mfeBridge consistently instead of direct globalThis.dispatchEvent\r\n mfeBridge.publish(NAVIGATION_CHANNELS.NAVIGATE, params)\r\n }\r\n return { navigate }\r\n}\r\n\r\nexport interface IMfeLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {\r\n internal?: boolean\r\n primaryHref: string\r\n secondaryHref?: string\r\n}\r\n\r\nexport const MfeLink: FC<IMfeLinkProps> = (props) => {\r\n const { internal, primaryHref, secondaryHref, onClick, ...rest } = props\r\n const { navigate } = useMfeNavigate()\r\n\r\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\r\n if (onClick) onClick(e)\r\n if (e.defaultPrevented) return\r\n if (internal && secondaryHref) {\r\n e.preventDefault()\r\n navigate({ primaryHref, secondaryHref, internal })\r\n return\r\n }\r\n // If not internal or no secondaryHref, let the anchor tag handle it\r\n }\r\n\r\n return <a {...rest} href={primaryHref} onClick={handleClick} />\r\n}\r\n\r\n// Define types to avoid direct imports\r\nexport type NavigateFunction<O = any> = (path: string, options?: O) => void\r\n\r\nexport interface IMfeNavigateProviderProps {\r\n navigate: NavigateFunction\r\n}\r\n\r\nexport const MfeNavigateProvider: FC<IMfeNavigateProviderProps> = ({ navigate }) => {\r\n useEffect(() => {\r\n const unsubscribe = mfeBridge.subscribe(NAVIGATION_CHANNELS.NAVIGATE, (payload: IMfeNavigate) => {\r\n const { primaryHref, secondaryHref, options } = payload\r\n if (!primaryHref) return\r\n // Navigate to secondaryHref if available, otherwise fallback to primaryHref\r\n const url = secondaryHref || primaryHref || '/'\r\n if (options?.target === '_blank') {\r\n // Only open in new window if in browser environment\r\n if (isBrowser()) {\r\n window.open(`${url}`, '_blank')\r\n }\r\n return\r\n }\r\n navigate(url, options)\r\n })\r\n return () => unsubscribe() // Unsubscribe from the event\r\n }, [navigate])\r\n return <></>\r\n}\r\n"],"names":["NAVIGATION_CHANNELS","NAVIGATE","useMfeNavigate","navigate","params","mfeBridge","publish","MfeLink","props","internal","primaryHref","secondaryHref","onClick","rest","_objectWithoutProperties","_excluded","_jsx","_objectSpread","href","e","defaultPrevented","preventDefault","MfeNavigateProvider","_ref","useEffect","unsubscribe","subscribe","payload","options","url","target","isBrowser","window","open","concat"],"mappings":"kVAKaA,EAAsB,CACjCC,SAAU,2BAuBNC,EAAiB,WAKrB,MAAO,CAAEC,SAJQ,SAACC,GAEhBC,EAAUC,QAAQN,EAAoBC,SAAUG,EACjD,EAEH,EAQaG,EAA6B,SAACC,GACzC,IAAQC,EAA2DD,EAA3DC,SAAUC,EAAiDF,EAAjDE,YAAaC,EAAoCH,EAApCG,cAAeC,EAAqBJ,EAArBI,QAAYC,EAAIC,EAAKN,EAAKO,GAChEZ,EAAaD,IAAbC,SAaR,OAAOa,EAAA,IAAAC,EAAAA,KAAOJ,GAAI,GAAA,CAAEK,KAAMR,EAAaE,QAXnB,SAACO,GAEnB,GADIP,GAASA,EAAQO,IACjBA,EAAEC,iBACN,OAAIX,GAAYE,GACdQ,EAAEE,sBACFlB,EAAS,CAAEO,YAAAA,EAAaC,cAAAA,EAAeF,SAAAA,UAFzC,CAMD,IAGH,EASaa,EAAqD,SAAlCC,GAAmD,IAAdpB,EAAQoB,EAARpB,SAkBnE,OAjBAqB,GAAU,WACR,IAAMC,EAAcpB,EAAUqB,UAAU1B,EAAoBC,UAAU,SAAC0B,GACrE,IAAQjB,EAAwCiB,EAAxCjB,YAAaC,EAA2BgB,EAA3BhB,cAAeiB,EAAYD,EAAZC,QACpC,GAAKlB,EAAL,CAEA,IAAMmB,EAAMlB,GAAiBD,GAAe,IACpB,YAApBkB,aAAO,EAAPA,EAASE,QAOb3B,EAAS0B,EAAKD,GALRG,KACFC,OAAOC,KAAIC,GAAAA,OAAIL,GAAO,SANR,CAWpB,IACA,OAAO,WAAA,OAAMJ,GAAa,CAC5B,GAAG,CAACtB,IACGa,OACT"}
@@ -0,0 +1,3 @@
1
+ export declare const useCheckScrolled: () => {
2
+ isScrolled: boolean;
3
+ };
@@ -0,0 +1 @@
1
+ export declare const useDebounce: <T>(value: T, delay: number) => T;
@@ -1,4 +1,4 @@
1
- export declare const useCheckScrolled: () => {
2
- isScrolled: boolean;
3
- };
4
- export declare const useDebounce: <T>(value: T, delay: number) => T;
1
+ export { useCheckScrolled } from './check-scrolled';
2
+ export { useDebounce } from './debounce';
3
+ export { useFetchData, errorMessageHandler } from './use-fetch-data';
4
+ export type { FetcherFunction } from './use-fetch-data';
@@ -0,0 +1,11 @@
1
+ export declare const errorMessageHandler: (error: any, options?: {
2
+ message?: string;
3
+ logAll?: boolean;
4
+ }) => {
5
+ isAbortError: boolean;
6
+ };
7
+ export type FetcherFunction<T> = (signal?: AbortSignal) => Promise<T>;
8
+ export declare function useFetchData<T, F extends FetcherFunction<T>>(fetcher: F): {
9
+ data: Awaited<ReturnType<F>> | undefined;
10
+ loading: boolean;
11
+ };
@@ -15,7 +15,7 @@ export interface ILoginResponse {
15
15
  user?: IUser;
16
16
  error?: string;
17
17
  }
18
- export interface IAuthProviderProps {
18
+ export interface IMfeAuthProviderProps {
19
19
  children?: React.ReactNode;
20
20
  onLogin?: (params: ILoginParams) => Promise<ILoginResponse | void>;
21
21
  onLogout?: () => Promise<boolean | void>;
@@ -38,8 +38,8 @@ export interface IAuthProviderProps {
38
38
  *
39
39
  * Host can customize login/logout behavior by providing custom handlers.
40
40
  */
41
- export declare const AuthProvider: React.FC<IAuthProviderProps>;
42
- export declare function useAuth(): {
41
+ export declare const MfeAuthProvider: React.FC<IMfeAuthProviderProps>;
42
+ export declare function useMfeAuth(): {
43
43
  login: (username: string, password: string) => void;
44
44
  logout: () => void;
45
45
  isAuthenticated: boolean;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ interface IDebugPanelProps {
3
+ title?: string;
4
+ style?: React.CSSProperties;
5
+ channelPrefix?: string;
6
+ }
7
+ export declare const MfeAuthDebugPanel: React.FC<IDebugPanelProps>;
8
+ export {};
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { IAuthState, IUser } from './auth.types';
3
- import { type IAuthProviderProps } from './auth';
3
+ import { type IMfeAuthProviderProps } from './auth';
4
4
  /**
5
5
  * Props for the SSR-compatible auth provider
6
6
  */
@@ -21,11 +21,11 @@ interface ISsrAuthProviderProps {
21
21
  [key: string]: any;
22
22
  };
23
23
  /** Custom login handler */
24
- onLogin?: IAuthProviderProps['onLogin'];
24
+ onLogin?: IMfeAuthProviderProps['onLogin'];
25
25
  /** Custom logout handler */
26
- onLogout?: IAuthProviderProps['onLogout'];
26
+ onLogout?: IMfeAuthProviderProps['onLogout'];
27
27
  /** Auth state change subscription */
28
- onAuthChange?: IAuthProviderProps['onAuthChange'];
28
+ onAuthChange?: IMfeAuthProviderProps['onAuthChange'];
29
29
  }
30
30
  /**
31
31
  * Auth provider component that supports SSR
@@ -5,33 +5,9 @@
5
5
  * multiple micro-frontends. The cart state is synchronized using the
6
6
  * mfeBridge communication system and persisted in localStorage.
7
7
  */
8
- /** Communication channels for cart operations */
9
- export declare const CART_CHANNELS: {
10
- /** Add an item to the cart */
11
- ADD: string;
12
- /** Remove an item from the cart */
13
- REMOVE: string;
14
- /** Clear all items from the cart */
15
- CLEAR: string;
16
- /** Request initial cart data (when a new MFE loads) */
17
- INIT_REQUEST: string;
18
- /** Response with cart data (to initialize a new MFE) */
19
- INIT_RESPONSE: string;
20
- /** Update the entire cart at once */
21
- UPDATE: string;
22
- };
23
- /**
24
- * Shopping cart item structure
25
- */
26
- export interface ICartItem {
27
- /** Unique identifier for the item */
28
- id: number;
29
- /** Display name of the item */
30
- name: string;
31
- /** Quantity of this item in the cart */
32
- quantity: number;
33
- /** Price per unit of the item */
34
- price: number;
8
+ import { ICartItem } from './cart.types';
9
+ export interface IMfeCartStoreConfigs {
10
+ storageKey: string;
35
11
  }
36
12
  /**
37
13
  * Hook to manage cart state across microFE
@@ -40,8 +16,8 @@ export interface ICartItem {
40
16
  * - Listen for cart events (add, remove, clear, update)
41
17
  * - Provide current cart state
42
18
  */
43
- export declare const useCartStore: () => {
44
- items: ICartItem[];
19
+ export declare function useMfeCartStore<O = any, T extends ICartItem<O> = ICartItem<O>>(configs?: IMfeCartStoreConfigs): {
20
+ items: T[];
45
21
  totalItems: number;
46
22
  };
47
23
  /**
@@ -51,9 +27,9 @@ export declare const useCartStore: () => {
51
27
  * - Use mfeEventBridge to communicate with other microFEs
52
28
  * - Provide add, remove, clear, and update actions
53
29
  */
54
- export declare const useCartActions: () => {
55
- addToCart: (item: ICartItem) => void;
56
- removeFromCart: (itemId: number) => void;
30
+ export declare function useMfeCartActions<O = any, T extends ICartItem<O> = ICartItem<O>>(): {
31
+ addToCart: (item: T) => void;
32
+ removeFromCart: (productId: string) => void;
57
33
  clearCart: () => void;
58
- updateCart: (items: ICartItem[]) => void;
34
+ updateCart: (items: T[]) => void;
59
35
  };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * cart.types.ts - Type definitions for the shopping cart system
3
+ */
4
+ export type CartItemType = 'Media' | 'Audio';
5
+ /**
6
+ * Shopping cart item structure
7
+ */
8
+ export interface ICartItem<O = any> {
9
+ ProductId: string;
10
+ PricePackageId: string;
11
+ Amount: number;
12
+ SocialUrl?: string;
13
+ Type?: CartItemType;
14
+ ProductName?: string;
15
+ Options?: O;
16
+ }
17
+ /** Communication channels for cart operations */
18
+ export declare const CART_CHANNELS: {
19
+ /** Add an item to the cart */
20
+ readonly ADD: "mfe:cart:add";
21
+ /** Remove an item from the cart */
22
+ readonly REMOVE: "mfe:cart:remove";
23
+ /** Clear all items from the cart */
24
+ readonly CLEAR: "mfe:cart:clear";
25
+ /** Request initial cart data (when a new MFE loads) */
26
+ readonly INIT_REQUEST: "mfe:cart:init_request";
27
+ /** Response with cart data (to initialize a new MFE) */
28
+ readonly INIT_RESPONSE: "mfe:cart:init_response";
29
+ /** Update the entire cart at once */
30
+ readonly UPDATE: "mfe:cart:update";
31
+ };
@@ -5,19 +5,22 @@
5
5
  * Only the public API is exported here, internal implementation details are hidden.
6
6
  */
7
7
  export { mfeBridge } from './mfe-bridge';
8
- export { AuthProvider } from './auth';
9
- export type { IAuthProviderProps, ILoginParams, ILoginResponse } from './auth';
10
- export { useAuth } from './auth';
8
+ export { MfeAuthProvider } from './auth';
9
+ export type { IMfeAuthProviderProps, ILoginParams, ILoginResponse } from './auth';
10
+ export { useMfeAuth } from './auth';
11
11
  export type { IAuthState, IUser } from './auth.types';
12
12
  export { AUTH_CHANNELS } from './auth.types';
13
13
  export { SsrAuthProvider } from './auth.ssr';
14
- export { useCartStore, useCartActions } from './cart';
15
- export type { ICartItem } from './cart';
16
- export { CART_CHANNELS } from './cart';
14
+ export { useMfeCartStore, useMfeCartActions } from './cart';
15
+ export type { ICartItem } from './cart.types';
16
+ export { CART_CHANNELS } from './cart.types';
17
17
  export { SsrCartProvider } from './cart.ssr';
18
- export { useMfeNavigate, MfeLink, MfeNavigateReactProvider } from './navigation';
19
- export type { IMfeNavigate, IMfeLinkProps, NavigateFunction, AppSite, IMfeNavigateReactProviderProps } from './navigation';
18
+ export { useMfeNavigate, MfeLink, MfeNavigateProvider } from './navigation';
19
+ export type { IMfeNavigate, IMfeLinkProps, NavigateFunction, AppSite, IMfeNavigateProviderProps } from './navigation';
20
20
  export { NAVIGATION_CHANNELS } from './navigation';
21
21
  export { isBrowser } from './environment';
22
22
  export { HydrationGuard, useHydration } from './hydration-helper';
23
23
  export type { IHydrationState } from './hydration-helper';
24
+ export { MfeAuthDebugPanel } from './auth.debug';
25
+ export { MfeCartDebugPanel } from './cart.debug';
26
+ export { MfeNavigateDebugPanel } from './navigation.debug';
@@ -25,7 +25,7 @@ export interface IMfeLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorEleme
25
25
  }
26
26
  export declare const MfeLink: FC<IMfeLinkProps>;
27
27
  export type NavigateFunction<O = any> = (path: string, options?: O) => void;
28
- export interface IMfeNavigateReactProviderProps {
28
+ export interface IMfeNavigateProviderProps {
29
29
  navigate: NavigateFunction;
30
30
  }
31
- export declare const MfeNavigateReactProvider: FC<IMfeNavigateReactProviderProps>;
31
+ export declare const MfeNavigateProvider: FC<IMfeNavigateProviderProps>;
@@ -5,7 +5,7 @@
5
5
  * to ensure they're available to consumers.
6
6
  */
7
7
  export type { IAuthState, IUser } from './auth.types';
8
- export type { IAuthProviderProps, ILoginParams, ILoginResponse } from './auth';
9
- export type { ICartItem } from './cart';
10
- export type { AppSite, IMfeNavigate, IMfeNavigateHref, IMfeLinkProps, NavigateFunction, IMfeNavigateReactProviderProps } from './navigation';
8
+ export type { IMfeAuthProviderProps as IAuthProviderProps, ILoginParams, ILoginResponse } from './auth';
9
+ export type { ICartItem } from './cart.types';
10
+ export type { AppSite, IMfeNavigate, IMfeNavigateHref, IMfeLinkProps, NavigateFunction, IMfeNavigateProviderProps as IMfeNavigateReactProviderProps } from './navigation';
11
11
  export type { IHydrationState } from './hydration-helper';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dinocollab-core",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",