@amplifyup/sdk 0.1.61 → 0.1.63

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.
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { createContext, memo, useState, useEffect, Fragment as Fragment$1, useContext, Component } from 'react';
2
+ import { createContext, memo, useState, useEffect, Fragment as Fragment$1, useContext, Component, useMemo, useRef } from 'react';
3
3
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
4
4
  import 'marked';
5
5
 
@@ -405,6 +405,159 @@ function isComposerPreview() {
405
405
  return false;
406
406
  }
407
407
 
408
+ // src/field-envelope.ts
409
+ var FIELDS_BRAND = Symbol("amplifyup.fields");
410
+ function isBrandedFields(value) {
411
+ return !!value && typeof value === "object" && FIELDS_BRAND in value;
412
+ }
413
+ function brandFields(bag) {
414
+ if (isBrandedFields(bag)) return bag;
415
+ Object.defineProperty(bag, FIELDS_BRAND, {
416
+ value: true,
417
+ enumerable: false,
418
+ configurable: false
419
+ });
420
+ return bag;
421
+ }
422
+ function isFieldEnvelope(value) {
423
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
424
+ const rec = value;
425
+ return typeof rec.name === "string" && "value" in rec && !("url" in rec);
426
+ }
427
+ function isPortableImageShape(value) {
428
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
429
+ return "url" in value;
430
+ }
431
+ function isEntryRefItem(value) {
432
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
433
+ const rec = value;
434
+ return typeof rec.id === "string" && rec.id.trim().length > 0 || typeof rec._id === "string" && rec._id.trim().length > 0 || typeof rec.docId === "string" && rec.docId.trim().length > 0;
435
+ }
436
+ function isRepeaterArray(value) {
437
+ if (!Array.isArray(value) || value.length === 0) return false;
438
+ const sample = value.find((item) => item != null);
439
+ if (sample === void 0) return false;
440
+ if (typeof sample !== "object" || Array.isArray(sample)) return false;
441
+ if (isPortableImageShape(sample)) return false;
442
+ if (isEntryRefItem(sample)) return false;
443
+ if (sample.$$typeof) return false;
444
+ return true;
445
+ }
446
+ function joinPath(prefix, key) {
447
+ return prefix ? `${prefix}.${key}` : key;
448
+ }
449
+ function emptyValue(raw) {
450
+ if (raw === void 0) return null;
451
+ return raw;
452
+ }
453
+ function toFieldEnvelopes(source, prefix = "") {
454
+ const input = source && typeof source === "object" && !Array.isArray(source) ? source : {};
455
+ if (isBrandedFields(input)) {
456
+ return input;
457
+ }
458
+ const out = {};
459
+ for (const [key, raw] of Object.entries(input)) {
460
+ const path = joinPath(prefix, key);
461
+ if (isFieldEnvelope(raw)) {
462
+ const inner = raw.value;
463
+ if (isRepeaterArray(inner)) {
464
+ out[key] = {
465
+ value: envelopeRepeaterItems(inner, raw.name || path),
466
+ name: raw.name || path
467
+ };
468
+ continue;
469
+ }
470
+ out[key] = { value: raw.value ?? null, name: raw.name || path };
471
+ continue;
472
+ }
473
+ if (isRepeaterArray(raw)) {
474
+ out[key] = { value: envelopeRepeaterItems(raw, path), name: path };
475
+ continue;
476
+ }
477
+ if (raw && typeof raw === "object" && !Array.isArray(raw) && !isPortableImageShape(raw) && !raw.$$typeof) {
478
+ out[key] = toFieldEnvelopes(raw, path);
479
+ continue;
480
+ }
481
+ out[key] = { value: emptyValue(raw), name: path };
482
+ }
483
+ return brandFields(out);
484
+ }
485
+ function envelopeRepeaterItems(items, prefix) {
486
+ return items.map((item, i) => {
487
+ const path = joinPath(prefix, String(i));
488
+ if (isBrandedFields(item)) return item;
489
+ if (item && typeof item === "object" && !Array.isArray(item)) {
490
+ return toFieldEnvelopes(item, path);
491
+ }
492
+ return toFieldEnvelopes({}, path);
493
+ });
494
+ }
495
+ function attachFieldEnvelopes(props) {
496
+ const raw = props && typeof props === "object" ? { ...props } : {};
497
+ if (isBrandedFields(raw.fields)) return raw;
498
+ const { fields: existing, ...content } = raw;
499
+ const source = existing && typeof existing === "object" && !isFieldEnvelope(existing) ? existing : content;
500
+ return { ...raw, fields: toFieldEnvelopes(source) };
501
+ }
502
+ function walkLayoutNodes(nodes) {
503
+ if (!Array.isArray(nodes)) return;
504
+ for (const node of nodes) {
505
+ if (!node || typeof node !== "object") continue;
506
+ const rec = node;
507
+ rec.props = attachFieldEnvelopes(rec.props);
508
+ for (const slot of rec.slots || []) {
509
+ walkLayoutNodes(slot.children);
510
+ }
511
+ }
512
+ }
513
+ function envelopePageConfig(page) {
514
+ if (!page || typeof page !== "object") return page ?? null;
515
+ const tree = page.layoutTree;
516
+ if (Array.isArray(tree)) walkLayoutNodes(tree);
517
+ return page;
518
+ }
519
+ function collectFieldPatches(props) {
520
+ const out = [];
521
+ const walkRepeater = (items, prefix) => {
522
+ items.forEach((item, i) => {
523
+ const itemPath = joinPath(prefix, String(i));
524
+ if (isBrandedFields(item) || item && typeof item === "object" && !Array.isArray(item) && !isFieldEnvelope(item)) {
525
+ walk(item, itemPath);
526
+ }
527
+ });
528
+ };
529
+ const walk = (obj, prefix) => {
530
+ for (const [key, raw] of Object.entries(obj)) {
531
+ if (key === "fields" && raw && typeof raw === "object" && !Array.isArray(raw) && !isFieldEnvelope(raw)) {
532
+ walk(raw, prefix);
533
+ continue;
534
+ }
535
+ const path = joinPath(prefix, key);
536
+ if (isFieldEnvelope(raw)) {
537
+ if (isRepeaterArray(raw.value)) {
538
+ walkRepeater(raw.value, raw.name || path);
539
+ continue;
540
+ }
541
+ out.push({ name: raw.name || path, value: raw.value });
542
+ continue;
543
+ }
544
+ if (isRepeaterArray(raw)) {
545
+ walkRepeater(raw, path);
546
+ continue;
547
+ }
548
+ if (raw && typeof raw === "object" && !Array.isArray(raw) && !isPortableImageShape(raw) && !raw.$$typeof) {
549
+ walk(raw, path);
550
+ continue;
551
+ }
552
+ out.push({ name: path, value: emptyValue(raw) });
553
+ }
554
+ };
555
+ if (props && typeof props === "object" && !Array.isArray(props)) {
556
+ walk(props, "");
557
+ }
558
+ return out;
559
+ }
560
+
408
561
  // src/page-context.ts
409
562
  var defaultLog = {
410
563
  warn: (...args) => {
@@ -553,7 +706,70 @@ function mergeEventContext(properties, attached) {
553
706
  ...attached.pageRoute ? { pageRoute: attached.pageRoute } : {}
554
707
  };
555
708
  }
709
+ var PAGE_RESOURCE_MARKER = "__amplifyupPageResource";
710
+ function isPageResourceSentinel(value) {
711
+ return !!value && typeof value === "object" && !Array.isArray(value) && typeof value[PAGE_RESOURCE_MARKER] === "string";
712
+ }
713
+ function getByDotPath(source, path) {
714
+ if (!path) return source;
715
+ const parts = path.split(".").filter(Boolean);
716
+ let cur = source;
717
+ for (const part of parts) {
718
+ if (cur == null || typeof cur !== "object" || Array.isArray(cur)) {
719
+ return void 0;
720
+ }
721
+ cur = cur[part];
722
+ }
723
+ return cur;
724
+ }
725
+ function hydratePageResourceValue(value, fields) {
726
+ if (!isPageResourceSentinel(value)) return value;
727
+ if (!fields) return null;
728
+ if (value.path) return getByDotPath(fields, value.path) ?? null;
729
+ return fields;
730
+ }
731
+ function hydrateFieldsBag(bag, fields) {
732
+ const out = {};
733
+ for (const [key, val] of Object.entries(bag)) {
734
+ if (val && typeof val === "object" && !Array.isArray(val) && typeof val.name === "string" && "value" in val && !("url" in val)) {
735
+ const env = val;
736
+ out[key] = {
737
+ name: env.name,
738
+ value: isPageResourceSentinel(env.value) ? hydratePageResourceValue(env.value, fields) : env.value
739
+ };
740
+ continue;
741
+ }
742
+ if (val && typeof val === "object" && !Array.isArray(val) && !("url" in val)) {
743
+ out[key] = hydrateFieldsBag(val, fields);
744
+ continue;
745
+ }
746
+ out[key] = isPageResourceSentinel(val) ? hydratePageResourceValue(val, fields) : val;
747
+ }
748
+ return out;
749
+ }
750
+ function hydratePageResourceProps(props, fields) {
751
+ const source = props && typeof props === "object" ? props : {};
752
+ const out = { ...source };
753
+ if (out.fields && typeof out.fields === "object" && !Array.isArray(out.fields)) {
754
+ const next = hydrateFieldsBag(out.fields, fields);
755
+ out.fields = isBrandedFields(out.fields) ? brandFields(next) : next;
756
+ }
757
+ for (const [key, val] of Object.entries(out)) {
758
+ if (key === "fields") continue;
759
+ if (isPageResourceSentinel(val)) {
760
+ out[key] = hydratePageResourceValue(val, fields);
761
+ }
762
+ }
763
+ return out;
764
+ }
765
+
766
+ // src/page-resource-runtime.ts
767
+ var pageResourceFields = null;
556
768
  function setPageResourceFields(fields) {
769
+ pageResourceFields = fields && typeof fields === "object" ? fields : null;
770
+ }
771
+ function getPageResourceFields() {
772
+ return pageResourceFields;
557
773
  }
558
774
 
559
775
  // src/debug.ts
@@ -1236,6 +1452,7 @@ var AmplifyUpSDK = class {
1236
1452
  this.resolvedPageData,
1237
1453
  this.resolvedPageRoute
1238
1454
  );
1455
+ setPageResourceFields(null);
1239
1456
  return;
1240
1457
  }
1241
1458
  this.attachedPageContext = applyPageContext(this.pendingPageContext, {
@@ -1664,7 +1881,7 @@ Available Console Commands:
1664
1881
  this.refreshEventTracking();
1665
1882
  }, 800);
1666
1883
  }
1667
- return pageConfig;
1884
+ return envelopePageConfig(pageConfig);
1668
1885
  }
1669
1886
  /**
1670
1887
  * Set up view-level event tracking based on configuration
@@ -3037,31 +3254,83 @@ function getSDK(adapter) {
3037
3254
  var trackContentView = (contentId, contentType, properties) => getSDK().trackContentView(contentId, contentType, properties);
3038
3255
  var refreshEventTracking = () => getSDK().refreshEventTracking();
3039
3256
  getSDK();
3040
- createContext(null);
3041
- function useLiveComposerProps(layoutNodeId, props) {
3042
- const [patch, setPatch] = useState(null);
3043
- useEffect(() => {
3044
- setPatch(null);
3045
- const matchesNode = (nodeId) => {
3046
- if (nodeId && layoutNodeId && String(nodeId) !== String(layoutNodeId)) {
3047
- return false;
3048
- }
3049
- return true;
3257
+
3258
+ // src/composer-store.ts
3259
+ var ComposerFieldStore = class {
3260
+ constructor() {
3261
+ this.values = /* @__PURE__ */ new Map();
3262
+ this.listeners = /* @__PURE__ */ new Map();
3263
+ }
3264
+ get(name) {
3265
+ return this.values.has(name) ? this.values.get(name) : void 0;
3266
+ }
3267
+ set(name, value) {
3268
+ if (!name) return;
3269
+ this.values.set(name, value);
3270
+ const set = this.listeners.get(name);
3271
+ if (!set) return;
3272
+ for (const fn of set) fn();
3273
+ }
3274
+ subscribe(name, fn) {
3275
+ if (!name) return () => {
3276
+ };
3277
+ let set = this.listeners.get(name);
3278
+ if (!set) {
3279
+ set = /* @__PURE__ */ new Set();
3280
+ this.listeners.set(name, set);
3281
+ }
3282
+ set.add(fn);
3283
+ return () => {
3284
+ set.delete(fn);
3285
+ if (set.size === 0) this.listeners.delete(name);
3050
3286
  };
3287
+ }
3288
+ keys() {
3289
+ return [...this.values.keys()];
3290
+ }
3291
+ delete(name) {
3292
+ if (!name || !this.values.has(name)) return;
3293
+ this.values.delete(name);
3294
+ const set = this.listeners.get(name);
3295
+ if (!set) return;
3296
+ for (const fn of set) fn();
3297
+ }
3298
+ };
3299
+ var ComposerStoreContext = createContext(null);
3300
+ function matchesNode(eventNodeId, layoutNodeId) {
3301
+ if (eventNodeId && layoutNodeId && String(eventNodeId) !== String(layoutNodeId)) {
3302
+ return false;
3303
+ }
3304
+ return true;
3305
+ }
3306
+ function ComposerProvider({
3307
+ layoutNodeId,
3308
+ children
3309
+ }) {
3310
+ const storeRef = useRef(null);
3311
+ if (!storeRef.current) storeRef.current = new ComposerFieldStore();
3312
+ const store = storeRef.current;
3313
+ useEffect(() => {
3051
3314
  const applyField = (fieldName, value, nodeId) => {
3052
3315
  if (!fieldName || typeof fieldName !== "string") return;
3053
- if (!matchesNode(nodeId)) return;
3054
- setPatch((prev) => ({ ...prev || {}, [fieldName]: value }));
3316
+ if (!matchesNode(nodeId, layoutNodeId)) return;
3317
+ store.set(fieldName, value);
3318
+ if (value && typeof value === "object") {
3319
+ for (const patch of collectFieldPatches(
3320
+ toFieldEnvelopes({ [fieldName]: value })
3321
+ )) {
3322
+ store.set(patch.name, patch.value);
3323
+ }
3324
+ }
3055
3325
  };
3056
3326
  const applyProps = (nextProps, nodeId) => {
3057
3327
  if (!nextProps || typeof nextProps !== "object" || Array.isArray(nextProps)) {
3058
3328
  return;
3059
3329
  }
3060
- if (!matchesNode(nodeId)) return;
3061
- setPatch((prev) => ({
3062
- ...prev || {},
3063
- ...nextProps
3064
- }));
3330
+ if (!matchesNode(nodeId, layoutNodeId)) return;
3331
+ for (const patch of collectFieldPatches(nextProps)) {
3332
+ store.set(patch.name, patch.value);
3333
+ }
3065
3334
  };
3066
3335
  const onPatch = (event) => {
3067
3336
  const detail = event.detail || {};
@@ -3087,9 +3356,19 @@ function useLiveComposerProps(layoutNodeId, props) {
3087
3356
  window.removeEventListener("amplifyup:props-patch", onPropsPatch);
3088
3357
  window.removeEventListener("message", onMessage);
3089
3358
  };
3090
- }, [layoutNodeId]);
3091
- return patch ? { ...props, ...patch } : props;
3359
+ }, [layoutNodeId, store]);
3360
+ return /* @__PURE__ */ jsx(ComposerStoreContext.Provider, { value: store, children });
3361
+ }
3362
+ function MaybeComposerProvider({
3363
+ enabled,
3364
+ layoutNodeId,
3365
+ children
3366
+ }) {
3367
+ const content = useMemo(() => children, [children]);
3368
+ if (!enabled) return /* @__PURE__ */ jsx(Fragment, { children: content });
3369
+ return /* @__PURE__ */ jsx(ComposerProvider, { layoutNodeId, children });
3092
3370
  }
3371
+ createContext(null);
3093
3372
  var usePathname = null;
3094
3373
  if (typeof window !== "undefined") {
3095
3374
  try {
@@ -3109,9 +3388,19 @@ function useAmplifyUp() {
3109
3388
  return context;
3110
3389
  }
3111
3390
  function nodeRenderProps(node) {
3391
+ const settings = node.settings || {};
3392
+ const hydrated = hydratePageResourceProps(
3393
+ node.props || {},
3394
+ getPageResourceFields()
3395
+ );
3396
+ const fields = hydrated.fields;
3397
+ const branded = isBrandedFields(fields) ? fields : brandFields(
3398
+ fields && typeof fields === "object" ? fields : {}
3399
+ );
3112
3400
  return {
3113
- ...node.settings || {},
3114
- ...node.props || {}
3401
+ ...settings,
3402
+ ...hydrated,
3403
+ fields: branded
3115
3404
  };
3116
3405
  }
3117
3406
  var ComponentRenderBoundary = class extends Component {
@@ -3161,17 +3450,24 @@ var ComponentRenderBoundary = class extends Component {
3161
3450
  return this.props.children;
3162
3451
  }
3163
3452
  };
3164
- function LiveNodeRender({
3453
+ function NodeWithFields({
3165
3454
  nodeId,
3166
3455
  componentId,
3167
3456
  props,
3168
3457
  slots,
3169
- renderComponent
3458
+ renderComponent,
3459
+ composerPreview
3170
3460
  }) {
3171
- const liveProps = useLiveComposerProps(nodeId, props);
3172
- return /* @__PURE__ */ jsx(Fragment, { children: renderComponent(componentId, liveProps, slots, {
3173
- layoutNodeId: nodeId
3174
- }) });
3461
+ return /* @__PURE__ */ jsx(
3462
+ MaybeComposerProvider,
3463
+ {
3464
+ enabled: !!(composerPreview || isComposerPreview()),
3465
+ layoutNodeId: nodeId,
3466
+ children: renderComponent(componentId, props, slots, {
3467
+ layoutNodeId: nodeId
3468
+ })
3469
+ }
3470
+ );
3175
3471
  }
3176
3472
  function AmplifyRendererInner({
3177
3473
  renderComponent,
@@ -3527,13 +3823,14 @@ function AmplifyRendererInner({
3527
3823
  componentId: node.componentId,
3528
3824
  nodeId: node.id,
3529
3825
  children: /* @__PURE__ */ jsx(
3530
- LiveNodeRender,
3826
+ NodeWithFields,
3531
3827
  {
3532
3828
  nodeId: node.id,
3533
3829
  componentId: node.componentId,
3534
3830
  props: nodeRenderProps(node),
3535
3831
  slots: slotsToPass,
3536
- renderComponent
3832
+ renderComponent,
3833
+ composerPreview
3537
3834
  }
3538
3835
  )
3539
3836
  }