@amplifyup/sdk 0.1.53 → 0.1.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use client';
2
- import React, { createContext, useState, useEffect, useContext, Fragment as Fragment$1, useSyncExternalStore, useRef, Component } from 'react';
2
+ import React, { createContext, memo, useState, useEffect, useContext, Fragment as Fragment$1, Component, useRef, useSyncExternalStore } from 'react';
3
3
  import { marked } from 'marked';
4
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
5
5
 
6
6
  /* @amplifyup/sdk - https://amplifyup.ai */
7
7
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
@@ -608,6 +608,49 @@ function getPageResourceFields() {
608
608
  return pageResourceFields;
609
609
  }
610
610
 
611
+ // src/debug.ts
612
+ function envFlag(value) {
613
+ if (!value) return false;
614
+ const v = value.trim().toLowerCase();
615
+ return v === "1" || v === "true" || v === "yes";
616
+ }
617
+ function readAmplifyUpDebugEnv() {
618
+ try {
619
+ if (typeof process === "undefined") return false;
620
+ return envFlag(process.env.NEXT_PUBLIC_AMPLIFYUP_DEBUG) || envFlag(process.env.AMPLIFYUP_DEBUG);
621
+ } catch {
622
+ return false;
623
+ }
624
+ }
625
+ var configDebug;
626
+ function setAmplifyUpDebug(enabled) {
627
+ configDebug = enabled;
628
+ }
629
+ function isAmplifyUpDebug() {
630
+ if (configDebug === true) return true;
631
+ if (configDebug === false) return false;
632
+ return readAmplifyUpDebugEnv();
633
+ }
634
+ var onceKeys = /* @__PURE__ */ new Set();
635
+ var onceRoute = "";
636
+ function resetOnceIfRouteChanged() {
637
+ const route = typeof window !== "undefined" ? window.location.pathname : "";
638
+ if (route === onceRoute) return;
639
+ onceKeys.clear();
640
+ onceRoute = route;
641
+ }
642
+ function sdkDebug(...args) {
643
+ if (!isAmplifyUpDebug()) return;
644
+ console.log(...args);
645
+ }
646
+ function sdkDebugOnce(key, ...args) {
647
+ if (!isAmplifyUpDebug()) return;
648
+ resetOnceIfRouteChanged();
649
+ if (onceKeys.has(key)) return;
650
+ onceKeys.add(key);
651
+ console.log(...args);
652
+ }
653
+
611
654
  // src/edge/normalizeRoute.ts
612
655
  function normalizeRoute(route) {
613
656
  let path = String(route || "").trim();
@@ -1181,13 +1224,13 @@ var AmplifyUpSDK = class {
1181
1224
  }
1182
1225
  this.config = {
1183
1226
  trackingId: previewOverrides.trackingId || config.trackingId,
1184
- debug: config.debug ?? true,
1185
- // Enable debug by default
1227
+ debug: config.debug ?? readAmplifyUpDebugEnv(),
1186
1228
  target: this.target,
1187
1229
  dev: config.dev,
1188
1230
  ...config.siteId ? { siteId: config.siteId } : {},
1189
1231
  ...config.pageContext ? { pageContext: config.pageContext } : {}
1190
1232
  };
1233
+ setAmplifyUpDebug(!!this.config.debug);
1191
1234
  if (config.pageContext) {
1192
1235
  this.pendingPageContext = config.pageContext;
1193
1236
  this.recomputeAttachedContext();
@@ -3434,11 +3477,9 @@ function EmptySlotHint({
3434
3477
  }
3435
3478
  var ComponentContext = createContext(null);
3436
3479
  function useLiveComposerProps(layoutNodeId, props) {
3437
- const [live, setLive] = useState(props);
3438
- useEffect(() => {
3439
- setLive(props);
3440
- }, [props]);
3480
+ const [patch, setPatch] = useState(null);
3441
3481
  useEffect(() => {
3482
+ setPatch(null);
3442
3483
  const matchesNode = (nodeId) => {
3443
3484
  if (nodeId && layoutNodeId && String(nodeId) !== String(layoutNodeId)) {
3444
3485
  return false;
@@ -3448,15 +3489,15 @@ function useLiveComposerProps(layoutNodeId, props) {
3448
3489
  const applyField = (fieldName, value, nodeId) => {
3449
3490
  if (!fieldName || typeof fieldName !== "string") return;
3450
3491
  if (!matchesNode(nodeId)) return;
3451
- setLive((prev) => ({ ...prev, [fieldName]: value }));
3492
+ setPatch((prev) => ({ ...prev || {}, [fieldName]: value }));
3452
3493
  };
3453
3494
  const applyProps = (nextProps, nodeId) => {
3454
3495
  if (!nextProps || typeof nextProps !== "object" || Array.isArray(nextProps)) {
3455
3496
  return;
3456
3497
  }
3457
3498
  if (!matchesNode(nodeId)) return;
3458
- setLive((prev) => ({
3459
- ...prev,
3499
+ setPatch((prev) => ({
3500
+ ...prev || {},
3460
3501
  ...nextProps
3461
3502
  }));
3462
3503
  };
@@ -3485,7 +3526,7 @@ function useLiveComposerProps(layoutNodeId, props) {
3485
3526
  window.removeEventListener("message", onMessage);
3486
3527
  };
3487
3528
  }, [layoutNodeId]);
3488
- return live;
3529
+ return patch ? { ...props, ...patch } : props;
3489
3530
  }
3490
3531
  function useComponentProps() {
3491
3532
  const context = useContext(ComponentContext);
@@ -3521,23 +3562,12 @@ function Slot({
3521
3562
  className
3522
3563
  }) {
3523
3564
  const context = useContext(ComponentContext);
3524
- console.log(`[Slot:${name}] Rendering slot`, {
3525
- hasContext: !!context,
3526
- availableSlotKeys: context?.slots ? Object.keys(context.slots) : [],
3527
- slotContent: context?.slots?.[name] ? "EXISTS" : "MISSING",
3528
- contextSlots: context?.slots
3529
- });
3530
3565
  if (!context) {
3531
3566
  console.warn(`[AmplifyUp SDK] Slot "${name}" used outside ComponentContextProvider`);
3532
3567
  return null;
3533
3568
  }
3534
3569
  const slotContent = context.slots?.[name];
3535
3570
  const isEmpty = !slotContent;
3536
- console.log(`[Slot:${name}] Slot state`, {
3537
- isEmpty,
3538
- hasSlotContent: !!slotContent,
3539
- slotContentType: slotContent ? typeof slotContent : "null"
3540
- });
3541
3571
  const isEditorMode = typeof window !== "undefined" && // Check for preview mode flag set by proxy
3542
3572
  (window.__AMPLIFYUP_PREVIEW_MODE__ === true || // Check URL query params
3543
3573
  new URLSearchParams(window.location.search).get("preview") === "true" || new URLSearchParams(window.location.search).get("visualEditor") === "true" || // Check if in iframe from orchestrator (check referrer hostname/port)
@@ -3549,17 +3579,15 @@ function Slot({
3549
3579
  return false;
3550
3580
  }
3551
3581
  })());
3552
- console.log(`[Slot:${name}] Editor mode detection`, {
3553
- isEditorMode,
3554
- isWindowDefined: typeof window !== "undefined",
3555
- previewModeFlag: typeof window !== "undefined" ? window.__AMPLIFYUP_PREVIEW_MODE__ : void 0,
3556
- urlParams: typeof window !== "undefined" ? {
3557
- preview: new URLSearchParams(window.location.search).get("preview"),
3558
- visualEditor: new URLSearchParams(window.location.search).get("visualEditor")
3559
- } : void 0,
3560
- inIframe: typeof window !== "undefined" ? window.self !== window.top : false,
3561
- referrer: typeof window !== "undefined" && document.referrer ? document.referrer : void 0
3562
- });
3582
+ sdkDebugOnce(
3583
+ `slot:${context.layoutNodeId || ""}:${name}`,
3584
+ `[Slot:${name}]`,
3585
+ {
3586
+ isEmpty,
3587
+ isEditorMode,
3588
+ availableSlotKeys: context.slots ? Object.keys(context.slots) : []
3589
+ }
3590
+ );
3563
3591
  return /* @__PURE__ */ jsx(
3564
3592
  "div",
3565
3593
  {
@@ -3784,9 +3812,10 @@ function ComposerInlineField({
3784
3812
  event.stopPropagation();
3785
3813
  },
3786
3814
  onClick: (event) => {
3815
+ if (!isComposerEditMode()) return;
3787
3816
  const link = event.target?.closest?.("a");
3788
3817
  if (link) event.preventDefault();
3789
- if (render && isComposerEditMode()) {
3818
+ if (render) {
3790
3819
  setEditing(true);
3791
3820
  }
3792
3821
  },
@@ -4199,7 +4228,7 @@ function LiveNodeRender({
4199
4228
  layoutNodeId: nodeId
4200
4229
  }) });
4201
4230
  }
4202
- function AmplifyRenderer({
4231
+ function AmplifyRendererInner({
4203
4232
  renderComponent,
4204
4233
  pageConfig: serverPageConfig,
4205
4234
  loadingComponent,
@@ -4341,14 +4370,22 @@ function AmplifyRenderer({
4341
4370
  return `${indent}- ${n.id} (${n.componentId || "?"})${slotsDesc ? "\n" + slotsDesc : ""}`;
4342
4371
  }).join("\n");
4343
4372
  };
4344
- console.log("[AmplifyRenderer] layoutTree received:\n%s", describeLayoutTree(layoutTree2));
4373
+ sdkDebugOnce(
4374
+ `layoutTree:${pageConfig?.id || ""}:${pageConfig?.route || ""}`,
4375
+ "[AmplifyRenderer] layoutTree received:\n%s",
4376
+ describeLayoutTree(layoutTree2)
4377
+ );
4345
4378
  if (typeof window !== "undefined" && window.parent && window.parent !== window) {
4346
4379
  const message = {
4347
4380
  type: "COMPONENT_TREE",
4348
4381
  tree: componentTree
4349
4382
  };
4350
4383
  window.parent.postMessage(message, "*");
4351
- console.log("[AmplifyRenderer] Sent component tree from layoutTree:", componentTree.length, "root components");
4384
+ sdkDebug(
4385
+ "[AmplifyRenderer] Sent component tree from layoutTree:",
4386
+ componentTree.length,
4387
+ "root components"
4388
+ );
4352
4389
  }
4353
4390
  }, [pageConfig]);
4354
4391
  useEffect(() => {
@@ -4499,7 +4536,7 @@ function AmplifyRenderer({
4499
4536
  );
4500
4537
  }
4501
4538
  let slotChildren = {};
4502
- console.log(`[AmplifyRenderer] Rendering node ${node.id} (${node.componentId})`, {
4539
+ sdkDebugOnce(`node:${node.id}`, `[AmplifyRenderer] Rendering node ${node.id} (${node.componentId})`, {
4503
4540
  hasSlots: !!(node.slots && node.slots.length > 0),
4504
4541
  slotCount: node.slots?.length || 0,
4505
4542
  slots: node.slots?.map((s) => ({ slotId: s.slotId, zoneId: s.zoneId, childrenCount: s.children?.length || 0 }))
@@ -4508,30 +4545,13 @@ function AmplifyRenderer({
4508
4545
  for (const slot of node.slots) {
4509
4546
  const slotKey = `${node.id}-${slot.slotId}`;
4510
4547
  let childrenToRender = [];
4511
- console.log(`[AmplifyRenderer] Processing slot ${slot.slotId} for node ${node.id}`, {
4512
- slotKey,
4513
- hasZoneId: !!slot.zoneId,
4514
- hasVariants: !!slot.variants,
4515
- hasVariantCache: !!variantCache[slotKey],
4516
- directChildrenCount: slot.children?.length || 0
4517
- });
4518
4548
  if (slot.zoneId && slot.variants && variantCache[slotKey]) {
4519
4549
  childrenToRender = variantCache[slotKey].children;
4520
- console.log(`[AmplifyRenderer] Using cached variant for slot ${slot.slotId}`, {
4521
- variantId: variantCache[slotKey].variantId,
4522
- childrenCount: childrenToRender.length
4523
- });
4524
4550
  } else if (slot.zoneId && slot.variants) {
4525
4551
  const defaultVariant = slot.variants.find((v) => v.isDefault);
4526
4552
  childrenToRender = defaultVariant?.children || [];
4527
- console.log(`[AmplifyRenderer] Using default variant for slot ${slot.slotId}`, {
4528
- childrenCount: childrenToRender.length
4529
- });
4530
4553
  } else {
4531
4554
  childrenToRender = Array.isArray(slot.children) ? slot.children : [];
4532
- console.log(`[AmplifyRenderer] Using direct children for slot ${slot.slotId}`, {
4533
- childrenCount: childrenToRender.length
4534
- });
4535
4555
  }
4536
4556
  const safeChildren = Array.isArray(childrenToRender) ? childrenToRender : [];
4537
4557
  slotChildren[slot.slotId] = /* @__PURE__ */ jsx(
@@ -4546,10 +4566,6 @@ function AmplifyRenderer({
4546
4566
  },
4547
4567
  slot.slotId
4548
4568
  );
4549
- console.log(`[AmplifyRenderer] Created slot content for ${slot.slotId}`, {
4550
- slotId: slot.slotId,
4551
- renderedChildrenCount: childrenToRender.length
4552
- });
4553
4569
  }
4554
4570
  }
4555
4571
  const slotsToPass = Object.keys(slotChildren).length > 0 ? slotChildren : void 0;
@@ -4587,6 +4603,7 @@ function AmplifyRenderer({
4587
4603
  }
4588
4604
  ) : layoutTree.map((node) => /* @__PURE__ */ jsx("div", { children: renderNode(node) }, node.id)) });
4589
4605
  }
4606
+ var AmplifyRenderer = memo(AmplifyRendererInner);
4590
4607
  function defaultPreviewCanvas() {
4591
4608
  return /* @__PURE__ */ jsx(
4592
4609
  "div",
@@ -4690,6 +4707,12 @@ if (typeof window !== "undefined") {
4690
4707
  }
4691
4708
  }
4692
4709
  var AmplifyUpContext = createContext(null);
4710
+ function normalizeRoutePath2(route) {
4711
+ if (!route) return "";
4712
+ const path = route.split("?")[0] || "/";
4713
+ if (path.length > 1 && path.endsWith("/")) return path.replace(/\/+$/, "");
4714
+ return path || "/";
4715
+ }
4693
4716
  function AmplifyUpProvider({
4694
4717
  children,
4695
4718
  config,
@@ -4717,6 +4740,7 @@ function AmplifyUpProvider({
4717
4740
  }
4718
4741
  return currentPath;
4719
4742
  };
4743
+ const loadedRouteRef = useRef(null);
4720
4744
  const nextPathname = usePathname ? usePathname() : null;
4721
4745
  const [pathname, setPathname] = useState(() => {
4722
4746
  if (typeof window !== "undefined") {
@@ -4750,56 +4774,46 @@ function AmplifyUpProvider({
4750
4774
  };
4751
4775
  }
4752
4776
  }, [nextPathname]);
4753
- useEffect(() => {
4754
- let cancelled = false;
4755
- const sdk = getSDK();
4756
- sdk.init({
4757
- ...config,
4758
- ...pageContext ? { pageContext } : {}
4759
- }).then(() => {
4760
- if (!cancelled) {
4761
- setInitialized(true);
4762
- }
4763
- }).catch((err) => {
4764
- if (cancelled) return;
4765
- console.error("Failed to initialize AmplifyUp SDK:", err);
4766
- setError("Failed to initialize tracking");
4767
- setLoading(false);
4768
- });
4769
- return () => {
4770
- cancelled = true;
4771
- };
4772
- }, [config.trackingId, config.target, config.debug, config.dev, config.siteId, pageContext]);
4777
+ const pageContextKey = pageContext ? `${pageContext.resourceType}:${pageContext.key}` : "";
4773
4778
  useEffect(() => {
4774
4779
  if (!initialized || !pageContext) return;
4775
4780
  getSDK().setPageContext(pageContext);
4776
- }, [initialized, pageContext]);
4781
+ }, [initialized, pageContextKey]);
4777
4782
  useEffect(() => {
4778
- if (!initialized) return;
4779
4783
  let cancelled = false;
4780
- const load = async () => {
4784
+ const sdk = getSDK();
4785
+ const run = async () => {
4781
4786
  try {
4787
+ await sdk.init({
4788
+ ...config,
4789
+ ...pageContext ? { pageContext } : {}
4790
+ });
4791
+ if (cancelled) return;
4792
+ if (pageContext) sdk.setPageContext(pageContext);
4782
4793
  const actualRoute = getActualRoute();
4783
4794
  if (!actualRoute) {
4795
+ setInitialized(true);
4784
4796
  setLoading(false);
4785
4797
  return;
4786
4798
  }
4787
- const sdk = getSDK();
4788
4799
  sdk.routeChange(actualRoute);
4789
4800
  const preview = isComposerPreview();
4790
4801
  const overlay = preview || config.clientPersonalization !== false;
4791
4802
  if (!overlay) {
4803
+ setInitialized(true);
4792
4804
  setPageConfig(null);
4793
4805
  setLoading(false);
4794
4806
  return;
4795
4807
  }
4796
- setPageConfig(null);
4797
- setError(null);
4798
- setLoading(false);
4808
+ if (loadedRouteRef.current && loadedRouteRef.current !== actualRoute) {
4809
+ setPageConfig(null);
4810
+ setError(null);
4811
+ }
4799
4812
  const edgeUrl = sdk.getEdgeUrl();
4800
4813
  const orchestratorUrl = sdk.getOrchestratorUrl();
4801
4814
  const trackingId = sdk.getTrackingId();
4802
4815
  if (!trackingId || !orchestratorUrl || !edgeUrl) {
4816
+ setInitialized(true);
4803
4817
  setError("SDK not initialized");
4804
4818
  setLoading(false);
4805
4819
  return;
@@ -4835,28 +4849,37 @@ function AmplifyUpProvider({
4835
4849
  fetchOrchestratorPage: (route, isPreview) => sdk.fetchPageConfig(route, isPreview)
4836
4850
  });
4837
4851
  if (cancelled) return;
4838
- setSource(result.source);
4839
- setMeta(result.meta);
4840
- setError(result.error);
4841
- if (!result.pageConfig) {
4842
- setPageConfig({
4843
- id: "default",
4844
- route: actualRoute,
4845
- title: "Page Not Configured",
4846
- description: "This page has not been published yet.",
4847
- layoutTree: []
4848
- });
4849
- } else {
4850
- setPageConfig(result.pageConfig);
4852
+ const nextConfig = result.pageConfig || {
4853
+ id: "default",
4854
+ route: actualRoute,
4855
+ title: "Page Not Configured",
4856
+ description: "This page has not been published yet.",
4857
+ layoutTree: []
4858
+ };
4859
+ setInitialized(true);
4860
+ setSource((prev) => prev === result.source ? prev : result.source);
4861
+ setMeta(
4862
+ (prev) => prev === result.meta || JSON.stringify(prev) === JSON.stringify(result.meta) ? prev : result.meta
4863
+ );
4864
+ setError((prev) => prev === result.error ? prev : result.error);
4865
+ setPageConfig((prev) => {
4866
+ if (prev && prev.id === nextConfig.id && normalizeRoutePath2(prev.route) === normalizeRoutePath2(nextConfig.route) && JSON.stringify(prev.layoutTree) === JSON.stringify(nextConfig.layoutTree)) {
4867
+ return prev;
4868
+ }
4869
+ return nextConfig;
4870
+ });
4871
+ if (result.pageConfig) {
4851
4872
  sdk.applyResolvedPageData(
4852
4873
  result.pageConfig.pageData || null,
4853
4874
  result.pageConfig.route,
4854
4875
  extractRouteParams(result.pageConfig.route, actualRoute)
4855
4876
  );
4856
4877
  }
4878
+ loadedRouteRef.current = actualRoute;
4857
4879
  } catch (err) {
4858
4880
  if (cancelled) return;
4859
4881
  console.error("Error fetching page config:", err);
4882
+ setInitialized(true);
4860
4883
  setError(err instanceof Error ? err.message : "Unknown error");
4861
4884
  setSource(null);
4862
4885
  setMeta(null);
@@ -4864,11 +4887,20 @@ function AmplifyUpProvider({
4864
4887
  if (!cancelled) setLoading(false);
4865
4888
  }
4866
4889
  };
4867
- void load();
4890
+ void run();
4868
4891
  return () => {
4869
4892
  cancelled = true;
4870
4893
  };
4871
- }, [pathname, initialized, config.clientPersonalization]);
4894
+ }, [
4895
+ pathname,
4896
+ config.trackingId,
4897
+ config.target,
4898
+ config.debug,
4899
+ config.dev,
4900
+ config.siteId,
4901
+ config.clientPersonalization,
4902
+ pageContextKey
4903
+ ]);
4872
4904
  return /* @__PURE__ */ jsx(
4873
4905
  AmplifyUpContext.Provider,
4874
4906
  {