remote-components 0.0.37 → 0.0.39

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 (36) hide show
  1. package/dist/html/host.cjs +78 -0
  2. package/dist/html/host.cjs.map +1 -1
  3. package/dist/html/host.js +78 -0
  4. package/dist/html/host.js.map +1 -1
  5. package/dist/internal/next/host/app-router-client.cjs +5 -1
  6. package/dist/internal/next/host/app-router-client.cjs.map +1 -1
  7. package/dist/internal/next/host/app-router-client.js +5 -1
  8. package/dist/internal/next/host/app-router-client.js.map +1 -1
  9. package/dist/internal/next/remote/render-server.cjs.map +1 -1
  10. package/dist/internal/next/remote/render-server.d.ts +13 -0
  11. package/dist/internal/next/remote/render-server.js.map +1 -1
  12. package/dist/internal/shared/client/get-client-src.cjs +39 -0
  13. package/dist/internal/shared/client/get-client-src.cjs.map +1 -0
  14. package/dist/internal/shared/client/get-client-src.d.ts +7 -0
  15. package/dist/internal/shared/client/get-client-src.js +15 -0
  16. package/dist/internal/shared/client/get-client-src.js.map +1 -0
  17. package/dist/internal/shared/ssr/fetch-remote-component.cjs +14 -10
  18. package/dist/internal/shared/ssr/fetch-remote-component.cjs.map +1 -1
  19. package/dist/internal/shared/ssr/fetch-remote-component.js +14 -10
  20. package/dist/internal/shared/ssr/fetch-remote-component.js.map +1 -1
  21. package/dist/internal/shared/ssr/get-ssr-relative-path-base-url.cjs +34 -0
  22. package/dist/internal/shared/ssr/get-ssr-relative-path-base-url.cjs.map +1 -0
  23. package/dist/internal/shared/ssr/get-ssr-relative-path-base-url.d.ts +10 -0
  24. package/dist/internal/shared/ssr/get-ssr-relative-path-base-url.js +10 -0
  25. package/dist/internal/shared/ssr/get-ssr-relative-path-base-url.js.map +1 -0
  26. package/dist/next/host/client/index.cjs +41 -2
  27. package/dist/next/host/client/index.cjs.map +1 -1
  28. package/dist/next/host/client/index.d.ts +13 -0
  29. package/dist/next/host/client/index.js +41 -2
  30. package/dist/next/host/client/index.js.map +1 -1
  31. package/dist/react/index.cjs +41 -2
  32. package/dist/react/index.cjs.map +1 -1
  33. package/dist/react/index.d.ts +14 -1
  34. package/dist/react/index.js +41 -2
  35. package/dist/react/index.js.map +1 -1
  36. package/package.json +1 -1
@@ -35,6 +35,19 @@ interface RemoteComponentProps {
35
35
  additionalHeaders?: Headers | Record<string, string>;
36
36
  /** The children to use as a loading fallback until the remote component is loaded. */
37
37
  children?: React.ReactNode;
38
+ /** Called right before a new remote component load starts. */
39
+ onBeforeLoad?: (src: string | URL) => void;
40
+ /** Called when the remote component has been successfully loaded and mounted. */
41
+ onLoad?: (src: string | URL) => void;
42
+ /** Called when an error occurs while loading or mounting the remote component. */
43
+ onError?: (error: unknown) => void;
44
+ /** Called when a different remote component is loaded into the same wrapper. */
45
+ onChange?: (info: {
46
+ previousSrc: string | URL | null;
47
+ nextSrc: string | URL | null;
48
+ previousName: string | undefined;
49
+ nextName: string | undefined;
50
+ }) => void;
38
51
  }
39
52
 
40
53
  /**
@@ -1356,7 +1356,11 @@ function RemoteComponent({
1356
1356
  name: nameProp = "__vercel_remote_component",
1357
1357
  shared = {},
1358
1358
  additionalHeaders,
1359
- children
1359
+ children,
1360
+ onBeforeLoad,
1361
+ onLoad,
1362
+ onError,
1363
+ onChange
1360
1364
  }) {
1361
1365
  const name = useMemo(() => {
1362
1366
  if (typeof src === "string") {
@@ -1412,6 +1416,7 @@ function RemoteComponent({
1412
1416
  const prevUrlRef = useRef(null);
1413
1417
  const prevRemoteComponentContainerRef = useRef(null);
1414
1418
  const unmountRef = useRef(null);
1419
+ const prevNameRef = useRef(void 0);
1415
1420
  useLayoutEffect(() => {
1416
1421
  if (childrenRef.current.length > 0 && remoteComponent) {
1417
1422
  childrenRef.current.forEach((el) => {
@@ -1467,7 +1472,10 @@ function RemoteComponent({
1467
1472
  }, [shadowRoot, remoteComponent, name]);
1468
1473
  useEffect(() => {
1469
1474
  if (src && src !== prevSrcRef.current) {
1475
+ const previousSrc = prevSrcRef.current;
1476
+ const previousName = prevNameRef.current;
1470
1477
  prevSrcRef.current = src;
1478
+ onBeforeLoad?.(src);
1471
1479
  startTransition(async () => {
1472
1480
  try {
1473
1481
  let html = getRemoteComponentHtml(
@@ -1565,6 +1573,7 @@ function RemoteComponent({
1565
1573
  }
1566
1574
  prevIsRemoteComponentRef.current = isRemoteComponent;
1567
1575
  prevUrlRef.current = url;
1576
+ prevNameRef.current = remoteName;
1568
1577
  applyOriginToNodes(doc, url);
1569
1578
  const links = Array.from(
1570
1579
  doc.querySelectorAll("link[href]")
@@ -1670,6 +1679,14 @@ function RemoteComponent({
1670
1679
  );
1671
1680
  }
1672
1681
  if (isRemoteComponent) {
1682
+ if (previousSrc !== null) {
1683
+ onChange?.({
1684
+ previousSrc,
1685
+ nextSrc: src,
1686
+ previousName,
1687
+ nextName: remoteName
1688
+ });
1689
+ }
1673
1690
  setData(newData);
1674
1691
  if (shadowRoot) {
1675
1692
  let shadowRootHtml = component.innerHTML;
@@ -1686,6 +1703,7 @@ function RemoteComponent({
1686
1703
  await Promise.all(
1687
1704
  Array.from(mount).map((mountFn) => mountFn(shadowRoot))
1688
1705
  );
1706
+ onLoad?.(src);
1689
1707
  } else if (isolate === false) {
1690
1708
  setRemoteComponent(
1691
1709
  // TODO: remove wrapper div by converting HTML to RSC or React tree
@@ -1707,6 +1725,7 @@ function RemoteComponent({
1707
1725
  (mountFn) => mountFn(prevRemoteComponentContainerRef.current)
1708
1726
  )
1709
1727
  );
1728
+ onLoad?.(src);
1710
1729
  }
1711
1730
  } else {
1712
1731
  const result = await loadRemoteComponent({
@@ -1747,14 +1766,25 @@ function RemoteComponent({
1747
1766
  rsc.remove();
1748
1767
  }
1749
1768
  setData(newData);
1769
+ if (previousSrc !== null) {
1770
+ onChange?.({
1771
+ previousSrc,
1772
+ nextSrc: src,
1773
+ previousName,
1774
+ nextName: remoteName
1775
+ });
1776
+ }
1750
1777
  if (result.error) {
1751
1778
  setRemoteComponent(result.error);
1779
+ onError?.(result.error);
1752
1780
  } else {
1753
1781
  setRemoteComponent(result.component);
1782
+ onLoad?.(src);
1754
1783
  }
1755
1784
  }
1756
1785
  } catch (error) {
1757
1786
  setRemoteComponent(error);
1787
+ onError?.(error);
1758
1788
  }
1759
1789
  });
1760
1790
  }
@@ -1768,7 +1798,11 @@ function RemoteComponent({
1768
1798
  shadowRoot,
1769
1799
  additionalHeaders,
1770
1800
  reset,
1771
- id
1801
+ id,
1802
+ onBeforeLoad,
1803
+ onLoad,
1804
+ onError,
1805
+ onChange
1772
1806
  ]);
1773
1807
  if (remoteComponent instanceof Error) {
1774
1808
  throw remoteComponent;
@@ -1804,6 +1838,10 @@ function RemoteComponent({
1804
1838
  return Promise.all(
1805
1839
  Array.from(mount).map((mountFn) => mountFn(shadowRoot))
1806
1840
  );
1841
+ }).then(() => {
1842
+ if (src) {
1843
+ onLoad?.(src);
1844
+ }
1807
1845
  }).catch((e) => {
1808
1846
  const error = new RemoteComponentsError(
1809
1847
  `Error mounting remote component from "${url.href}"`,
@@ -1812,6 +1850,7 @@ function RemoteComponent({
1812
1850
  }
1813
1851
  );
1814
1852
  setRemoteComponent(error);
1853
+ onError?.(error);
1815
1854
  });
1816
1855
  }
1817
1856
  }