@measured/puck-plugin-heading-analyzer 0.19.0-canary.84a836b → 0.19.0-canary.a281c342

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/index.js CHANGED
@@ -199,7 +199,7 @@ init_react_import();
199
199
 
200
200
  // src/HeadingAnalyzer.tsx
201
201
  init_react_import();
202
- var import_react12 = require("react");
202
+ var import_react11 = require("react");
203
203
 
204
204
  // css-module:/home/runner/work/puck/puck/packages/plugin-heading-analyzer/src/HeadingAnalyzer.module.css#css-module
205
205
  init_react_import();
@@ -360,7 +360,7 @@ var ChevronRight = createLucideIcon("ChevronRight", [
360
360
 
361
361
  // ../core/lib/use-breadcrumbs.ts
362
362
  init_react_import();
363
- var import_react11 = require("react");
363
+ var import_react10 = require("react");
364
364
 
365
365
  // ../core/store/index.ts
366
366
  init_react_import();
@@ -368,28 +368,13 @@ init_react_import();
368
368
  // ../core/reducer/index.ts
369
369
  init_react_import();
370
370
 
371
- // ../core/reducer/data.ts
372
- init_react_import();
373
-
374
- // ../core/lib/reorder.ts
375
- init_react_import();
376
- var reorder = (list, startIndex, endIndex) => {
377
- const result = Array.from(list);
378
- const [removed] = result.splice(startIndex, 1);
379
- result.splice(endIndex, 0, removed);
380
- return result;
381
- };
382
-
383
- // ../core/lib/root-droppable-id.ts
371
+ // ../core/reducer/reduce.ts
384
372
  init_react_import();
385
- var rootAreaId = "root";
386
- var rootZone = "default-zone";
387
- var rootDroppableId = `${rootAreaId}:${rootZone}`;
388
373
 
389
374
  // ../core/lib/insert.ts
390
375
  init_react_import();
391
376
  var insert = (list, index, item) => {
392
- const result = Array.from(list);
377
+ const result = Array.from(list || []);
393
378
  result.splice(index, 0, item);
394
379
  return result;
395
380
  };
@@ -404,6 +389,14 @@ var remove = (list, index) => {
404
389
 
405
390
  // ../core/lib/setup-zone.ts
406
391
  init_react_import();
392
+
393
+ // ../core/lib/root-droppable-id.ts
394
+ init_react_import();
395
+ var rootAreaId = "root";
396
+ var rootZone = "default-zone";
397
+ var rootDroppableId = `${rootAreaId}:${rootZone}`;
398
+
399
+ // ../core/lib/setup-zone.ts
407
400
  var setupZone = (data, zoneKey) => {
408
401
  if (zoneKey === rootDroppableId) {
409
402
  return data;
@@ -415,29 +408,14 @@ var setupZone = (data, zoneKey) => {
415
408
  return newData;
416
409
  };
417
410
 
418
- // ../core/lib/replace.ts
419
- init_react_import();
420
- var replace = (list, index, newItem) => {
421
- const result = Array.from(list);
422
- result.splice(index, 1);
423
- result.splice(index, 0, newItem);
424
- return result;
425
- };
426
-
427
411
  // ../core/lib/get-item.ts
428
412
  init_react_import();
429
- function getItem(selector, data, dynamicProps = {}) {
430
- if (!selector.zone || selector.zone === rootDroppableId) {
431
- const item2 = data.content[selector.index];
432
- return (item2 == null ? void 0 : item2.props) ? __spreadProps(__spreadValues({}, item2), { props: dynamicProps[item2.props.id] || item2.props }) : void 0;
433
- }
434
- const item = setupZone(data, selector.zone).zones[selector.zone][selector.index];
435
- return (item == null ? void 0 : item.props) ? __spreadProps(__spreadValues({}, item), { props: dynamicProps[item.props.id] || item.props }) : void 0;
413
+ function getItem(selector, state) {
414
+ var _a, _b;
415
+ const zone = (_a = state.indexes.zones) == null ? void 0 : _a[selector.zone || rootDroppableId];
416
+ return zone ? (_b = state.indexes.nodes[zone.contentIds[selector.index]]) == null ? void 0 : _b.data : void 0;
436
417
  }
437
418
 
438
- // ../core/lib/reduce-related-zones.ts
439
- init_react_import();
440
-
441
419
  // ../core/lib/generate-id.ts
442
420
  init_react_import();
443
421
 
@@ -500,6 +478,49 @@ var v4_default = v4;
500
478
  // ../core/lib/generate-id.ts
501
479
  var generateId = (type) => type ? `${type}-${v4_default()}` : v4_default();
502
480
 
481
+ // ../core/lib/walk-tree.ts
482
+ init_react_import();
483
+
484
+ // ../core/lib/for-each-slot.ts
485
+ init_react_import();
486
+
487
+ // ../core/lib/is-slot.ts
488
+ init_react_import();
489
+ var isSlot = (prop) => {
490
+ var _a, _b;
491
+ return Array.isArray(prop) && typeof ((_a = prop[0]) == null ? void 0 : _a.type) === "string" && typeof ((_b = prop[0]) == null ? void 0 : _b.props) === "object";
492
+ };
493
+ var createIsSlotConfig = (config) => (itemType, propName, propValue) => {
494
+ var _a, _b;
495
+ const configForComponent = itemType === "root" ? config == null ? void 0 : config.root : config == null ? void 0 : config.components[itemType];
496
+ if (!configForComponent) return isSlot(propValue);
497
+ return ((_b = (_a = configForComponent.fields) == null ? void 0 : _a[propName]) == null ? void 0 : _b.type) === "slot";
498
+ };
499
+
500
+ // ../core/lib/for-each-slot.ts
501
+ var forEachSlot = (_0, _1, ..._2) => __async(void 0, [_0, _1, ..._2], function* (item, cb, recursive = false, isSlot2 = isSlot) {
502
+ const props = item.props || {};
503
+ const propKeys = Object.keys(props);
504
+ for (let i = 0; i < propKeys.length; i++) {
505
+ const propKey = propKeys[i];
506
+ const itemType = "type" in item ? item.type : "root";
507
+ if (isSlot2(itemType, propKey, props[propKey])) {
508
+ const content = props[propKey];
509
+ yield cb(props.id, propKey, content);
510
+ if (recursive) {
511
+ content.forEach(
512
+ (childItem) => __async(void 0, null, function* () {
513
+ return yield forEachSlot(childItem, cb, true, isSlot2);
514
+ })
515
+ );
516
+ }
517
+ }
518
+ }
519
+ });
520
+
521
+ // ../core/lib/for-related-zones.ts
522
+ init_react_import();
523
+
503
524
  // ../core/lib/get-zone-id.ts
504
525
  init_react_import();
505
526
  var getZoneId = (zoneCompound) => {
@@ -512,302 +533,497 @@ var getZoneId = (zoneCompound) => {
512
533
  return [rootDroppableId, zoneCompound];
513
534
  };
514
535
 
515
- // ../core/lib/reduce-related-zones.ts
516
- function reduceRelatedZones(item, data, fn) {
536
+ // ../core/lib/for-related-zones.ts
537
+ function forRelatedZones(item, data, cb, path = []) {
538
+ Object.entries(data.zones || {}).forEach(([zoneCompound, content]) => {
539
+ const [parentId] = getZoneId(zoneCompound);
540
+ if (parentId === item.props.id) {
541
+ const newPath = [...path, zoneCompound];
542
+ content.forEach((item2) => forRelatedZones(item2, data, cb, newPath));
543
+ cb(path, zoneCompound, content);
544
+ }
545
+ });
546
+ }
547
+
548
+ // ../core/lib/strip-slots.ts
549
+ init_react_import();
550
+ var stripSlots = (data) => {
517
551
  return __spreadProps(__spreadValues({}, data), {
518
- zones: Object.keys(data.zones || {}).reduce(
519
- (acc, key) => {
520
- const [parentId] = getZoneId(key);
521
- if (parentId === item.props.id) {
522
- const zones = data.zones;
523
- return fn(acc, key, zones[key]);
552
+ props: Object.entries(data.props).reduce(
553
+ (acc, [propKey, propVal]) => {
554
+ if (isSlot(propVal)) {
555
+ return acc;
524
556
  }
525
- return __spreadProps(__spreadValues({}, acc), { [key]: data.zones[key] });
557
+ return __spreadProps(__spreadValues({}, acc), { [propKey]: propVal });
526
558
  },
527
- {}
559
+ { id: data.props.id }
528
560
  )
529
561
  });
530
- }
531
- var findRelatedByZoneId = (zoneId, data) => {
532
- const [zoneParentId] = getZoneId(zoneId);
533
- return (data.zones[zoneId] || []).reduce(
534
- (acc, zoneItem) => {
535
- const related = findRelatedByItem(zoneItem, data);
536
- if (zoneItem.props.id === zoneParentId) {
537
- return __spreadProps(__spreadValues(__spreadValues({}, acc), related), { [zoneId]: zoneItem });
538
- }
539
- return __spreadValues(__spreadValues({}, acc), related);
540
- },
541
- {}
542
- );
543
562
  };
544
- var findRelatedByItem = (item, data) => {
545
- return Object.keys(data.zones || {}).reduce(
546
- (acc, zoneId) => {
547
- const [zoneParentId] = getZoneId(zoneId);
548
- if (item.props.id === zoneParentId) {
549
- const related = findRelatedByZoneId(zoneId, data);
550
- return __spreadProps(__spreadValues(__spreadValues({}, acc), related), {
551
- [zoneId]: data.zones[zoneId]
552
- });
553
- }
554
- return acc;
563
+
564
+ // ../core/lib/walk-tree.ts
565
+ function walkTree(state, config, mapContent = (content) => content, mapNodeOrSkip = (item) => item) {
566
+ var _a;
567
+ let newZones = {};
568
+ const newZoneIndex = {};
569
+ const newNodeIndex = {};
570
+ const processContent = (path, zoneCompound, content, zoneType, newId) => {
571
+ var _a2;
572
+ const [parentId] = zoneCompound.split(":");
573
+ const mappedContent = ((_a2 = mapContent(content, zoneCompound, zoneType)) != null ? _a2 : content) || [];
574
+ const [_2, zone] = zoneCompound.split(":");
575
+ const newZoneCompound = `${newId || parentId}:${zone}`;
576
+ const newContent2 = mappedContent.map(
577
+ (zoneChild, index) => processItem(zoneChild, [...path, newZoneCompound], index)
578
+ );
579
+ newZoneIndex[newZoneCompound] = {
580
+ contentIds: newContent2.map((item) => item.props.id),
581
+ type: zoneType
582
+ };
583
+ return [newZoneCompound, newContent2];
584
+ };
585
+ const processRelatedZones = (item, newId, initialPath) => {
586
+ forRelatedZones(
587
+ item,
588
+ state.data,
589
+ (relatedPath, relatedZoneCompound, relatedContent) => {
590
+ const [zoneCompound, newContent2] = processContent(
591
+ relatedPath,
592
+ relatedZoneCompound,
593
+ relatedContent,
594
+ "dropzone",
595
+ newId
596
+ );
597
+ newZones[zoneCompound] = newContent2;
598
+ },
599
+ initialPath
600
+ );
601
+ };
602
+ const processItem = (item, path, index) => {
603
+ const mappedItem = mapNodeOrSkip(item, path, index);
604
+ if (!mappedItem) return item;
605
+ const id = mappedItem.props.id;
606
+ processRelatedZones(item, id, path);
607
+ const newProps = __spreadValues({}, mappedItem.props);
608
+ forEachSlot(
609
+ mappedItem,
610
+ (parentId2, slotId, content) => {
611
+ const zoneCompound = `${parentId2}:${slotId}`;
612
+ const [_2, newContent2] = processContent(
613
+ path,
614
+ zoneCompound,
615
+ content,
616
+ "slot",
617
+ parentId2
618
+ );
619
+ newProps[slotId] = newContent2;
620
+ },
621
+ false,
622
+ createIsSlotConfig(config)
623
+ );
624
+ const newItem = __spreadProps(__spreadValues({}, item), { props: newProps });
625
+ const thisZoneCompound = path[path.length - 1];
626
+ const [parentId, zone] = thisZoneCompound ? thisZoneCompound.split(":") : [null, ""];
627
+ newNodeIndex[id] = {
628
+ data: newItem,
629
+ flatData: stripSlots(newItem),
630
+ path,
631
+ parentId,
632
+ zone
633
+ };
634
+ const finalData = __spreadProps(__spreadValues({}, newItem), { props: __spreadValues({}, newItem.props) });
635
+ if (newProps.id === "root") {
636
+ delete finalData["type"];
637
+ delete finalData.props["id"];
638
+ }
639
+ return finalData;
640
+ };
641
+ const zones = state.data.zones || {};
642
+ const [_, newContent] = processContent(
643
+ [],
644
+ rootDroppableId,
645
+ state.data.content,
646
+ "root"
647
+ );
648
+ const processedContent = newContent;
649
+ const zonesAlreadyProcessed = Object.keys(newZones);
650
+ Object.keys(zones || {}).forEach((zoneCompound) => {
651
+ const [parentId] = zoneCompound.split(":");
652
+ if (zonesAlreadyProcessed.includes(zoneCompound)) {
653
+ return;
654
+ }
655
+ const [_2, newContent2] = processContent(
656
+ [rootDroppableId],
657
+ zoneCompound,
658
+ zones[zoneCompound],
659
+ "dropzone",
660
+ parentId
661
+ );
662
+ newZones[zoneCompound] = newContent2;
663
+ }, newZones);
664
+ const processedRoot = processItem(
665
+ {
666
+ type: "root",
667
+ props: __spreadProps(__spreadValues({}, (_a = state.data.root.props) != null ? _a : state.data.root), { id: "root" })
555
668
  },
556
- {}
669
+ [],
670
+ -1
557
671
  );
558
- };
559
- var removeRelatedZones = (item, data) => {
560
- const newData = __spreadValues({}, data);
561
- const related = findRelatedByItem(item, data);
562
- Object.keys(related).forEach((key) => {
563
- delete newData.zones[key];
672
+ const root = __spreadProps(__spreadValues({}, state.data.root), {
673
+ props: processedRoot.props
564
674
  });
565
- return newData;
566
- };
567
- function duplicateRelatedZones(item, data, newId) {
568
- return reduceRelatedZones(item, data, (acc, key, zone) => {
569
- const dupedZone = zone.map((zoneItem) => __spreadProps(__spreadValues({}, zoneItem), {
570
- props: __spreadProps(__spreadValues({}, zoneItem.props), { id: generateId(zoneItem.type) })
571
- }));
572
- const dupeOfDupes = dupedZone.reduce(
573
- (dupeOfDupes2, item2, index) => __spreadValues(__spreadValues({}, dupeOfDupes2), duplicateRelatedZones(zone[index], data, item2.props.id).zones),
574
- acc
575
- );
576
- const [_, zoneId] = getZoneId(key);
577
- return __spreadProps(__spreadValues({}, dupeOfDupes), {
578
- [key]: zone,
579
- [`${newId}:${zoneId}`]: dupedZone
580
- });
675
+ return __spreadProps(__spreadValues({}, state), {
676
+ data: {
677
+ root,
678
+ // root: state.data.root, // TODO changing root causes it's entire subtree to re-render. Let's keep this disabled until the performance issues are resolved in #644.
679
+ content: processedContent,
680
+ zones: __spreadValues(__spreadValues({}, state.data.zones), newZones)
681
+ },
682
+ indexes: {
683
+ nodes: __spreadValues(__spreadValues({}, state.indexes.nodes), newNodeIndex),
684
+ zones: __spreadValues(__spreadValues({}, state.indexes.zones), newZoneIndex)
685
+ }
581
686
  });
582
687
  }
583
688
 
584
- // ../core/reducer/data.ts
689
+ // ../core/reducer/reduce.ts
585
690
  var zoneCache = {};
586
- var replaceAction = (data, action) => {
587
- if (action.destinationZone === rootDroppableId) {
588
- return __spreadProps(__spreadValues({}, data), {
589
- content: replace(data.content, action.destinationIndex, action.data)
590
- });
591
- }
592
- const newData = setupZone(data, action.destinationZone);
593
- return __spreadProps(__spreadValues({}, newData), {
594
- zones: __spreadProps(__spreadValues({}, newData.zones), {
595
- [action.destinationZone]: replace(
596
- newData.zones[action.destinationZone],
597
- action.destinationIndex,
598
- action.data
599
- )
600
- })
601
- });
691
+ var getIdsForParent = (zoneCompound, state) => {
692
+ const [parentId] = zoneCompound.split(":");
693
+ const node = state.indexes.nodes[parentId];
694
+ return ((node == null ? void 0 : node.path) || []).map((p) => p.split(":")[0]);
602
695
  };
603
- function insertAction(data, action, config) {
696
+ function insertAction(state, action, config) {
697
+ const id = action.id || generateId(action.componentType);
604
698
  const emptyComponentData = {
605
699
  type: action.componentType,
606
700
  props: __spreadProps(__spreadValues({}, config.components[action.componentType].defaultProps || {}), {
607
- id: action.id || generateId(action.componentType)
701
+ id
608
702
  })
609
703
  };
610
- if (action.destinationZone === rootDroppableId) {
611
- return __spreadProps(__spreadValues({}, data), {
612
- content: insert(
613
- data.content,
614
- action.destinationIndex,
615
- emptyComponentData
616
- )
617
- });
618
- }
619
- const newData = setupZone(data, action.destinationZone);
620
- return __spreadProps(__spreadValues({}, data), {
621
- zones: __spreadProps(__spreadValues({}, newData.zones), {
622
- [action.destinationZone]: insert(
623
- newData.zones[action.destinationZone],
624
- action.destinationIndex,
625
- emptyComponentData
626
- )
627
- })
628
- });
704
+ const [parentId] = action.destinationZone.split(":");
705
+ const idsInPath = getIdsForParent(action.destinationZone, state);
706
+ return walkTree(
707
+ state,
708
+ config,
709
+ (content, zoneCompound) => {
710
+ if (zoneCompound === action.destinationZone) {
711
+ return insert(
712
+ content || [],
713
+ action.destinationIndex,
714
+ emptyComponentData
715
+ );
716
+ }
717
+ return content;
718
+ },
719
+ (childItem, path) => {
720
+ if (childItem.props.id === id || childItem.props.id === parentId) {
721
+ return childItem;
722
+ } else if (idsInPath.includes(childItem.props.id)) {
723
+ return childItem;
724
+ } else if (path.includes(action.destinationZone)) {
725
+ return childItem;
726
+ }
727
+ return null;
728
+ }
729
+ );
629
730
  }
630
- var reorderAction = (data, action) => {
631
- if (action.destinationZone === rootDroppableId) {
632
- return __spreadProps(__spreadValues({}, data), {
633
- content: reorder(
634
- data.content,
635
- action.sourceIndex,
636
- action.destinationIndex
637
- )
638
- });
731
+ var moveAction = (state, action, appStore) => {
732
+ if (action.sourceZone === action.destinationZone && action.sourceIndex === action.destinationIndex) {
733
+ return state;
639
734
  }
640
- const newData = setupZone(data, action.destinationZone);
641
- return __spreadProps(__spreadValues({}, data), {
642
- zones: __spreadProps(__spreadValues({}, newData.zones), {
643
- [action.destinationZone]: reorder(
644
- newData.zones[action.destinationZone],
645
- action.sourceIndex,
646
- action.destinationIndex
647
- )
648
- })
735
+ const item = getItem(
736
+ { zone: action.sourceZone, index: action.sourceIndex },
737
+ state
738
+ );
739
+ if (!item) return state;
740
+ const idsInSourcePath = getIdsForParent(action.sourceZone, state);
741
+ const idsInDestinationPath = getIdsForParent(action.destinationZone, state);
742
+ return walkTree(
743
+ state,
744
+ appStore.config,
745
+ (content, zoneCompound) => {
746
+ if (zoneCompound === action.sourceZone && zoneCompound === action.destinationZone) {
747
+ return insert(
748
+ remove(content, action.sourceIndex),
749
+ action.destinationIndex,
750
+ item
751
+ );
752
+ } else if (zoneCompound === action.sourceZone) {
753
+ return remove(content, action.sourceIndex);
754
+ } else if (zoneCompound === action.destinationZone) {
755
+ return insert(content, action.destinationIndex, item);
756
+ }
757
+ return content;
758
+ },
759
+ (childItem, path) => {
760
+ const [sourceZoneParent] = action.sourceZone.split(":");
761
+ const [destinationZoneParent] = action.destinationZone.split(":");
762
+ const childId = childItem.props.id;
763
+ if (sourceZoneParent === childId || destinationZoneParent === childId || item.props.id === childId || idsInSourcePath.indexOf(childId) > -1 || idsInDestinationPath.indexOf(childId) > -1 || path.includes(action.destinationZone)) {
764
+ return childItem;
765
+ }
766
+ return null;
767
+ }
768
+ );
769
+ };
770
+ var replaceAction = (state, action, appStore) => {
771
+ const [parentId] = action.destinationZone.split(":");
772
+ const idsInPath = getIdsForParent(action.destinationZone, state);
773
+ const originalId = state.indexes.zones[action.destinationZone].contentIds[action.destinationIndex];
774
+ const idChanged = originalId !== action.data.props.id;
775
+ if (idChanged) {
776
+ throw new Error(
777
+ `Can't change the id during a replace action. Please us "remove" and "insert" to define a new node.`
778
+ );
779
+ }
780
+ return walkTree(
781
+ state,
782
+ appStore.config,
783
+ (content, zoneCompound) => {
784
+ const newContent = [...content];
785
+ if (zoneCompound === action.destinationZone) {
786
+ newContent[action.destinationIndex] = action.data;
787
+ }
788
+ return newContent;
789
+ },
790
+ (childItem, path) => {
791
+ const pathIds = path.map((p) => p.split(":")[0]);
792
+ if (childItem.props.id === action.data.props.id) {
793
+ return action.data;
794
+ } else if (childItem.props.id === parentId) {
795
+ return childItem;
796
+ } else if (idsInPath.indexOf(childItem.props.id) > -1) {
797
+ return childItem;
798
+ } else if (pathIds.indexOf(action.data.props.id) > -1) {
799
+ return childItem;
800
+ }
801
+ return null;
802
+ }
803
+ );
804
+ };
805
+ var setAction = (state, action, appStore) => {
806
+ if (typeof action.state === "object") {
807
+ const newState = __spreadValues(__spreadValues({}, state), action.state);
808
+ if (action.state.indexes) {
809
+ console.warn(
810
+ "`set` is expensive and may cause unnecessary re-renders. Consider using a more atomic action instead."
811
+ );
812
+ return newState;
813
+ }
814
+ return walkTree(newState, appStore.config);
815
+ }
816
+ return __spreadValues(__spreadValues({}, state), action.state(state));
817
+ };
818
+ var removeAction = (state, action, appStore) => {
819
+ const item = getItem({ index: action.index, zone: action.zone }, state);
820
+ const [parentId] = action.zone.split(":");
821
+ const nodesToDelete = Object.entries(state.indexes.nodes).reduce(
822
+ (acc, [nodeId, nodeData]) => {
823
+ const pathIds = nodeData.path.map((p) => p.split(":")[0]);
824
+ if (pathIds.includes(item.props.id)) {
825
+ return [...acc, nodeId];
826
+ }
827
+ return acc;
828
+ },
829
+ [item.props.id]
830
+ );
831
+ const newState = walkTree(
832
+ state,
833
+ appStore.config,
834
+ (content, zoneCompound) => {
835
+ if (zoneCompound === action.zone) {
836
+ return remove(content, action.index);
837
+ }
838
+ return content;
839
+ },
840
+ (childItem, path) => {
841
+ const parentIds = path.map((p) => p.split(":")[0]);
842
+ if (childItem.props.id === parentId || childItem.props.id === item.props.id || parentIds.indexOf(item.props.id) > -1) {
843
+ return childItem;
844
+ }
845
+ return null;
846
+ }
847
+ );
848
+ Object.keys(newState.data.zones || {}).forEach((zoneCompound) => {
849
+ const parentId2 = zoneCompound.split(":")[0];
850
+ if (nodesToDelete.includes(parentId2) && newState.data.zones) {
851
+ delete newState.data.zones[zoneCompound];
852
+ }
853
+ });
854
+ Object.keys(newState.indexes.zones).forEach((zoneCompound) => {
855
+ const parentId2 = zoneCompound.split(":")[0];
856
+ if (nodesToDelete.includes(parentId2)) {
857
+ delete newState.indexes.zones[zoneCompound];
858
+ }
859
+ });
860
+ nodesToDelete.forEach((id) => {
861
+ delete newState.indexes.nodes[id];
649
862
  });
863
+ return newState;
650
864
  };
651
- function reduceData(data, action, config) {
865
+ function reduce(state, action, appStore) {
866
+ if (action.type === "set") {
867
+ return setAction(state, action, appStore);
868
+ }
652
869
  if (action.type === "insert") {
653
- return insertAction(data, action, config);
870
+ return insertAction(state, action, appStore.config);
871
+ }
872
+ if (action.type === "replace") {
873
+ return replaceAction(state, action, appStore);
874
+ }
875
+ if (action.type === "replaceRoot") {
876
+ return walkTree(
877
+ state,
878
+ appStore.config,
879
+ (content) => content,
880
+ (childItem) => {
881
+ if (childItem.props.id === "root") {
882
+ return __spreadProps(__spreadValues({}, childItem), {
883
+ props: __spreadValues(__spreadValues({}, childItem.props), action.root.props),
884
+ readOnly: action.root.readOnly
885
+ });
886
+ }
887
+ return childItem;
888
+ }
889
+ );
654
890
  }
655
891
  if (action.type === "duplicate") {
656
892
  const item = getItem(
657
893
  { index: action.sourceIndex, zone: action.sourceZone },
658
- data
894
+ state
659
895
  );
896
+ const idsInPath = getIdsForParent(action.sourceZone, state);
660
897
  const newItem = __spreadProps(__spreadValues({}, item), {
661
898
  props: __spreadProps(__spreadValues({}, item.props), {
662
899
  id: generateId(item.type)
663
900
  })
664
901
  });
665
- const dataWithRelatedDuplicated = duplicateRelatedZones(
666
- item,
667
- data,
668
- newItem.props.id
902
+ const modified = walkTree(
903
+ state,
904
+ appStore.config,
905
+ (content, zoneCompound) => {
906
+ if (zoneCompound === action.sourceZone) {
907
+ return insert(content, action.sourceIndex + 1, item);
908
+ }
909
+ return content;
910
+ },
911
+ (childItem, path, index) => {
912
+ const zoneCompound = path[path.length - 1];
913
+ const parents = path.map((p) => p.split(":")[0]);
914
+ if (parents.indexOf(newItem.props.id) > -1) {
915
+ return __spreadProps(__spreadValues({}, childItem), {
916
+ props: __spreadProps(__spreadValues({}, childItem.props), {
917
+ id: generateId(childItem.type)
918
+ })
919
+ });
920
+ }
921
+ if (zoneCompound === action.sourceZone && index === action.sourceIndex + 1) {
922
+ return newItem;
923
+ }
924
+ const [sourceZoneParent] = action.sourceZone.split(":");
925
+ if (sourceZoneParent === childItem.props.id || idsInPath.indexOf(childItem.props.id) > -1) {
926
+ return childItem;
927
+ }
928
+ return null;
929
+ }
669
930
  );
670
- if (action.sourceZone === rootDroppableId) {
671
- return __spreadProps(__spreadValues({}, dataWithRelatedDuplicated), {
672
- content: insert(data.content, action.sourceIndex + 1, newItem)
673
- });
674
- }
675
- return __spreadProps(__spreadValues({}, dataWithRelatedDuplicated), {
676
- zones: __spreadProps(__spreadValues({}, dataWithRelatedDuplicated.zones), {
677
- [action.sourceZone]: insert(
678
- dataWithRelatedDuplicated.zones[action.sourceZone],
679
- action.sourceIndex + 1,
680
- newItem
681
- )
931
+ return __spreadProps(__spreadValues({}, modified), {
932
+ ui: __spreadProps(__spreadValues({}, modified.ui), {
933
+ itemSelector: {
934
+ index: action.sourceIndex + 1,
935
+ zone: action.sourceZone
936
+ }
682
937
  })
683
938
  });
684
939
  }
685
940
  if (action.type === "reorder") {
686
- return reorderAction(data, action);
687
- }
688
- if (action.type === "move") {
689
- if (action.sourceZone === action.destinationZone && action.sourceIndex === action.destinationIndex) {
690
- return data;
691
- }
692
- const newData = setupZone(
693
- setupZone(data, action.sourceZone),
694
- action.destinationZone
695
- );
696
- const item = getItem(
697
- { zone: action.sourceZone, index: action.sourceIndex },
698
- newData
941
+ return moveAction(
942
+ state,
943
+ {
944
+ type: "move",
945
+ sourceIndex: action.sourceIndex,
946
+ sourceZone: action.destinationZone,
947
+ destinationIndex: action.destinationIndex,
948
+ destinationZone: action.destinationZone
949
+ },
950
+ appStore
699
951
  );
700
- if (action.sourceZone === action.destinationZone) {
701
- return reorderAction(data, __spreadProps(__spreadValues({}, action), { type: "reorder" }));
702
- }
703
- if (action.sourceZone === rootDroppableId) {
704
- return __spreadProps(__spreadValues({}, newData), {
705
- content: remove(newData.content, action.sourceIndex),
706
- zones: __spreadProps(__spreadValues({}, newData.zones), {
707
- [action.destinationZone]: insert(
708
- newData.zones[action.destinationZone],
709
- action.destinationIndex,
710
- item
711
- )
712
- })
713
- });
714
- }
715
- if (action.destinationZone === rootDroppableId) {
716
- return __spreadProps(__spreadValues({}, newData), {
717
- content: insert(newData.content, action.destinationIndex, item),
718
- zones: __spreadProps(__spreadValues({}, newData.zones), {
719
- [action.sourceZone]: remove(
720
- newData.zones[action.sourceZone],
721
- action.sourceIndex
722
- )
723
- })
724
- });
725
- }
726
- return __spreadProps(__spreadValues({}, newData), {
727
- zones: __spreadProps(__spreadValues({}, newData.zones), {
728
- [action.sourceZone]: remove(
729
- newData.zones[action.sourceZone],
730
- action.sourceIndex
731
- ),
732
- [action.destinationZone]: insert(
733
- newData.zones[action.destinationZone],
734
- action.destinationIndex,
735
- item
736
- )
737
- })
738
- });
739
952
  }
740
- if (action.type === "replace") {
741
- return replaceAction(data, action);
953
+ if (action.type === "move") {
954
+ return moveAction(state, action, appStore);
742
955
  }
743
956
  if (action.type === "remove") {
744
- const item = getItem({ index: action.index, zone: action.zone }, data);
745
- const dataWithRelatedRemoved = setupZone(
746
- removeRelatedZones(item, data),
747
- action.zone
748
- );
749
- if (action.zone === rootDroppableId) {
750
- return __spreadProps(__spreadValues({}, dataWithRelatedRemoved), {
751
- content: remove(data.content, action.index)
752
- });
753
- }
754
- return __spreadProps(__spreadValues({}, dataWithRelatedRemoved), {
755
- zones: __spreadProps(__spreadValues({}, dataWithRelatedRemoved.zones), {
756
- [action.zone]: remove(
757
- dataWithRelatedRemoved.zones[action.zone],
758
- action.index
759
- )
760
- })
761
- });
957
+ return removeAction(state, action, appStore);
762
958
  }
763
959
  if (action.type === "registerZone") {
764
960
  if (zoneCache[action.zone]) {
765
- return __spreadProps(__spreadValues({}, data), {
766
- zones: __spreadProps(__spreadValues({}, data.zones), {
767
- [action.zone]: zoneCache[action.zone]
961
+ return __spreadProps(__spreadValues({}, state), {
962
+ data: __spreadProps(__spreadValues({}, state.data), {
963
+ zones: __spreadProps(__spreadValues({}, state.data.zones), {
964
+ [action.zone]: zoneCache[action.zone]
965
+ })
966
+ }),
967
+ indexes: __spreadProps(__spreadValues({}, state.indexes), {
968
+ zones: __spreadProps(__spreadValues({}, state.indexes.zones), {
969
+ [action.zone]: __spreadProps(__spreadValues({}, state.indexes.zones[action.zone]), {
970
+ contentIds: zoneCache[action.zone].map((item) => item.props.id),
971
+ type: "dropzone"
972
+ })
973
+ })
768
974
  })
769
975
  });
770
976
  }
771
- return setupZone(data, action.zone);
977
+ return __spreadProps(__spreadValues({}, state), { data: setupZone(state.data, action.zone) });
772
978
  }
773
979
  if (action.type === "unregisterZone") {
774
- const _zones = __spreadValues({}, data.zones || {});
980
+ const _zones = __spreadValues({}, state.data.zones || {});
981
+ const zoneIndex = __spreadValues({}, state.indexes.zones || {});
775
982
  if (_zones[action.zone]) {
776
983
  zoneCache[action.zone] = _zones[action.zone];
777
984
  delete _zones[action.zone];
778
985
  }
779
- return __spreadProps(__spreadValues({}, data), { zones: _zones });
986
+ delete zoneIndex[action.zone];
987
+ return __spreadProps(__spreadValues({}, state), {
988
+ data: __spreadProps(__spreadValues({}, state.data), {
989
+ zones: _zones
990
+ }),
991
+ indexes: __spreadProps(__spreadValues({}, state.indexes), {
992
+ zones: zoneIndex
993
+ })
994
+ });
780
995
  }
781
996
  if (action.type === "setData") {
782
997
  if (typeof action.data === "object") {
783
- return __spreadValues(__spreadValues({}, data), action.data);
998
+ console.warn(
999
+ "`setData` is expensive and may cause unnecessary re-renders. Consider using a more atomic action instead."
1000
+ );
1001
+ return walkTree(
1002
+ __spreadProps(__spreadValues({}, state), {
1003
+ data: __spreadValues(__spreadValues({}, state.data), action.data)
1004
+ }),
1005
+ appStore.config
1006
+ );
784
1007
  }
785
- return __spreadValues(__spreadValues({}, data), action.data(data));
1008
+ return walkTree(
1009
+ __spreadProps(__spreadValues({}, state), {
1010
+ data: __spreadValues(__spreadValues({}, state.data), action.data(state.data))
1011
+ }),
1012
+ appStore.config
1013
+ );
786
1014
  }
787
- return data;
788
- }
789
-
790
- // ../core/reducer/state.ts
791
- init_react_import();
792
- var reduceUi = (ui, action) => {
793
1015
  if (action.type === "setUi") {
794
1016
  if (typeof action.ui === "object") {
795
- return __spreadValues(__spreadValues({}, ui), action.ui);
1017
+ return __spreadProps(__spreadValues({}, state), {
1018
+ ui: __spreadValues(__spreadValues({}, state.ui), action.ui)
1019
+ });
796
1020
  }
797
- return __spreadValues(__spreadValues({}, ui), action.ui(ui));
798
- }
799
- if (action.type === "duplicate") {
800
- return __spreadProps(__spreadValues({}, ui), {
801
- itemSelector: { index: action.sourceIndex + 1, zone: action.sourceZone }
1021
+ return __spreadProps(__spreadValues({}, state), {
1022
+ ui: __spreadValues(__spreadValues({}, state.ui), action.ui(state.ui))
802
1023
  });
803
1024
  }
804
- if (action.type === "remove") {
805
- return __spreadProps(__spreadValues({}, ui), {
806
- itemSelector: null
807
- });
808
- }
809
- return ui;
810
- };
1025
+ return state;
1026
+ }
811
1027
 
812
1028
  // ../core/reducer/actions.tsx
813
1029
  init_react_import();
@@ -830,25 +1046,15 @@ function storeInterceptor(reducer, record, onAction) {
830
1046
  return newAppState;
831
1047
  };
832
1048
  }
833
- var setAction = (state, action) => {
834
- if (typeof action.state === "object") {
835
- return __spreadValues(__spreadValues({}, state), action.state);
836
- }
837
- return __spreadValues(__spreadValues({}, state), action.state(state));
838
- };
839
1049
  function createReducer({
840
- config,
841
1050
  record,
842
- onAction
1051
+ onAction,
1052
+ appStore
843
1053
  }) {
844
1054
  return storeInterceptor(
845
1055
  (state, action) => {
846
- const data = reduceData(state.data, action, config);
847
- const ui = reduceUi(state.ui, action);
848
- if (action.type === "set") {
849
- return setAction(state, action);
850
- }
851
- return { data, ui };
1056
+ const result = reduce(state, action, appStore);
1057
+ return result;
852
1058
  },
853
1059
  record,
854
1060
  onAction
@@ -868,11 +1074,11 @@ init_react_import();
868
1074
  var createStoreImpl = (createState) => {
869
1075
  let state;
870
1076
  const listeners = /* @__PURE__ */ new Set();
871
- const setState = (partial, replace2) => {
1077
+ const setState = (partial, replace) => {
872
1078
  const nextState = typeof partial === "function" ? partial(state) : partial;
873
1079
  if (!Object.is(nextState, state)) {
874
1080
  const previousState = state;
875
- state = (replace2 != null ? replace2 : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState);
1081
+ state = (replace != null ? replace : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState);
876
1082
  listeners.forEach((listener) => listener(state, previousState));
877
1083
  }
878
1084
  };
@@ -936,208 +1142,8 @@ var subscribeWithSelectorImpl = (fn) => (set, get, api) => {
936
1142
  };
937
1143
  var subscribeWithSelector = subscribeWithSelectorImpl;
938
1144
 
939
- // ../core/lib/resolve-data.ts
940
- init_react_import();
941
-
942
- // ../core/lib/resolve-component-data.ts
943
- init_react_import();
944
-
945
- // ../core/lib/get-changed.ts
946
- init_react_import();
947
- var getChanged = (newItem, oldItem) => {
948
- return newItem ? Object.keys(newItem.props || {}).reduce((acc, item) => {
949
- const newItemProps = (newItem == null ? void 0 : newItem.props) || {};
950
- const oldItemProps = (oldItem == null ? void 0 : oldItem.props) || {};
951
- return __spreadProps(__spreadValues({}, acc), {
952
- [item]: oldItemProps[item] !== newItemProps[item]
953
- });
954
- }, {}) : {};
955
- };
956
-
957
- // ../core/lib/resolve-component-data.ts
958
- var cache = { lastChange: {} };
959
- var resolveComponentData = (_0, _1, ..._2) => __async(void 0, [_0, _1, ..._2], function* (item, config, metadata = {}, onResolveStart, onResolveEnd) {
960
- const configForItem = config.components[item.type];
961
- if (configForItem.resolveData) {
962
- const { item: oldItem = null, resolved = {} } = cache.lastChange[item.props.id] || {};
963
- if (item && item === oldItem) {
964
- return resolved;
965
- }
966
- const changed = getChanged(item, oldItem);
967
- if (onResolveStart) {
968
- onResolveStart(item);
969
- }
970
- const { props: resolvedProps, readOnly = {} } = yield configForItem.resolveData(item, {
971
- changed,
972
- lastData: oldItem,
973
- metadata
974
- });
975
- const resolvedItem = __spreadProps(__spreadValues({}, item), {
976
- props: __spreadValues(__spreadValues({}, item.props), resolvedProps)
977
- });
978
- if (Object.keys(readOnly).length) {
979
- resolvedItem.readOnly = readOnly;
980
- }
981
- cache.lastChange[item.props.id] = {
982
- item,
983
- resolved: resolvedItem
984
- };
985
- if (onResolveEnd) {
986
- onResolveEnd(resolvedItem);
987
- }
988
- return resolvedItem;
989
- }
990
- return item;
991
- });
992
-
993
- // ../core/lib/apply-dynamic-props.ts
994
- init_react_import();
995
- var applyDynamicProps = (data, dynamicProps, rootData) => {
996
- return __spreadProps(__spreadValues({}, data), {
997
- root: rootData ? __spreadValues(__spreadValues({}, data.root), rootData ? rootData : {}) : data.root,
998
- content: data.content.map((item) => {
999
- return dynamicProps[item.props.id] ? __spreadValues(__spreadValues({}, item), dynamicProps[item.props.id]) : item;
1000
- }),
1001
- zones: Object.keys(data.zones || {}).reduce((acc, zoneKey) => {
1002
- return __spreadProps(__spreadValues({}, acc), {
1003
- [zoneKey]: data.zones[zoneKey].map((item) => {
1004
- return dynamicProps[item.props.id] ? __spreadValues(__spreadValues({}, item), dynamicProps[item.props.id]) : item;
1005
- })
1006
- });
1007
- }, {})
1008
- });
1009
- };
1010
-
1011
- // ../core/lib/resolve-root-data.ts
1012
- init_react_import();
1013
- var cache2 = {};
1014
- function resolveRootData(data, config, metadata) {
1015
- return __async(this, null, function* () {
1016
- var _a, _b, _c, _d, _e;
1017
- if (((_a = config.root) == null ? void 0 : _a.resolveData) && data.root.props) {
1018
- if (((_b = cache2.lastChange) == null ? void 0 : _b.original) === data.root) {
1019
- return cache2.lastChange.resolved;
1020
- }
1021
- const changed = getChanged(data.root, (_c = cache2.lastChange) == null ? void 0 : _c.original);
1022
- const rootWithProps = data.root;
1023
- const resolvedRoot = yield (_e = config.root) == null ? void 0 : _e.resolveData(rootWithProps, {
1024
- changed,
1025
- lastData: ((_d = cache2.lastChange) == null ? void 0 : _d.original) || {},
1026
- metadata: metadata || {}
1027
- });
1028
- cache2.lastChange = {
1029
- original: data.root,
1030
- resolved: resolvedRoot
1031
- };
1032
- return __spreadProps(__spreadValues(__spreadValues({}, data.root), resolvedRoot), {
1033
- props: __spreadValues(__spreadValues({}, data.root.props), resolvedRoot.props)
1034
- });
1035
- }
1036
- return data.root;
1037
- });
1038
- }
1039
-
1040
- // ../core/lib/flatten-data.ts
1041
- init_react_import();
1042
- var flattenData = (data) => {
1043
- return Object.keys(data.zones || {}).reduce(
1044
- (acc, zone) => [...acc, ...data.zones[zone]],
1045
- data.content
1046
- );
1047
- };
1048
-
1049
- // ../core/lib/resolve-data.ts
1050
- var import_fast_deep_equal = __toESM(require_fast_deep_equal());
1051
- var resolveData = (newAppState, appStoreData) => {
1052
- const {
1053
- state: appState,
1054
- config,
1055
- dispatch,
1056
- resolveDataRuns,
1057
- setComponentLoading,
1058
- unsetComponentLoading,
1059
- metadata,
1060
- permissions
1061
- } = appStoreData;
1062
- const deferredSetStates = {};
1063
- const _setComponentLoading = (id, loading, defer = 0) => {
1064
- if (deferredSetStates[id]) {
1065
- clearTimeout(deferredSetStates[id]);
1066
- delete deferredSetStates[id];
1067
- }
1068
- deferredSetStates[id] = setTimeout(() => {
1069
- if (loading) {
1070
- setComponentLoading(id);
1071
- } else {
1072
- unsetComponentLoading(id);
1073
- }
1074
- delete deferredSetStates[id];
1075
- }, defer);
1076
- };
1077
- const runResolvers = () => __async(void 0, null, function* () {
1078
- const newData = newAppState.data;
1079
- const flatContent = flattenData(newData).filter(
1080
- (item) => {
1081
- var _a;
1082
- return !!((_a = config.components[item.type]) == null ? void 0 : _a.resolveData);
1083
- }
1084
- );
1085
- const applyIfChange = (dynamicDataMap, dynamicRoot) => {
1086
- const processed = applyDynamicProps(
1087
- __spreadValues({}, appState.data),
1088
- dynamicDataMap,
1089
- dynamicRoot
1090
- );
1091
- const processedAppState = __spreadProps(__spreadValues({}, appState), { data: processed });
1092
- const containsChanges = !(0, import_fast_deep_equal.default)(appState, processedAppState);
1093
- if (containsChanges) {
1094
- dispatch({
1095
- type: "set",
1096
- state: (prev) => __spreadProps(__spreadValues({}, prev), {
1097
- data: applyDynamicProps(prev.data, dynamicDataMap, dynamicRoot),
1098
- ui: resolveDataRuns > 0 ? __spreadValues(__spreadValues({}, prev.ui), newAppState.ui) : prev.ui
1099
- }),
1100
- recordHistory: resolveDataRuns > 0
1101
- });
1102
- }
1103
- };
1104
- const promises = [];
1105
- promises.push(
1106
- (() => __async(void 0, null, function* () {
1107
- _setComponentLoading("puck-root", true, 50);
1108
- const dynamicRoot = yield resolveRootData(newData, config, metadata);
1109
- applyIfChange({}, dynamicRoot);
1110
- _setComponentLoading("puck-root", false);
1111
- }))()
1112
- );
1113
- flatContent.forEach((item) => {
1114
- promises.push(
1115
- (() => __async(void 0, null, function* () {
1116
- permissions.resolvePermissions({ item }, true);
1117
- const dynamicData = yield resolveComponentData(
1118
- item,
1119
- config,
1120
- metadata,
1121
- (item2) => {
1122
- _setComponentLoading(item2.props.id, true, 50);
1123
- },
1124
- (item2) => {
1125
- deferredSetStates[item2.props.id];
1126
- _setComponentLoading(item2.props.id, false);
1127
- }
1128
- );
1129
- const dynamicDataMap = { [item.props.id]: dynamicData };
1130
- applyIfChange(dynamicDataMap);
1131
- }))()
1132
- );
1133
- });
1134
- yield Promise.all(promises);
1135
- });
1136
- return runResolvers();
1137
- };
1138
-
1139
1145
  // ../core/store/index.ts
1140
- var import_react10 = require("react");
1146
+ var import_react9 = require("react");
1141
1147
 
1142
1148
  // ../core/store/slices/history.ts
1143
1149
  init_react_import();
@@ -1253,31 +1259,14 @@ var createHistorySlice = (set, get) => {
1253
1259
 
1254
1260
  // ../core/store/slices/nodes.ts
1255
1261
  init_react_import();
1256
- var import_fast_deep_equal2 = __toESM(require_fast_deep_equal());
1257
- var import_react7 = require("react");
1258
- var partialDeepEqual = (newItem, existingItem) => {
1259
- const filteredExistingItem = Object.keys(newItem).reduce(
1260
- (acc, key) => __spreadProps(__spreadValues({}, acc), { [key]: existingItem[key] }),
1261
- {}
1262
- );
1263
- return (0, import_fast_deep_equal2.default)(newItem, filteredExistingItem);
1264
- };
1265
1262
  var createNodesSlice = (set, get) => ({
1266
1263
  nodes: {},
1267
1264
  registerNode: (id, node) => {
1268
1265
  const s = get().nodes;
1269
- if (s.nodes[id] && partialDeepEqual(node, s.nodes[id])) {
1270
- return;
1271
- }
1272
1266
  const emptyNode = {
1273
1267
  id,
1274
1268
  methods: { sync: () => null },
1275
- data: { props: { id }, type: "unknown" },
1276
- parentId: "",
1277
- zone: "",
1278
- path: [],
1279
- element: null,
1280
- index: -1
1269
+ element: null
1281
1270
  };
1282
1271
  const existingNode = s.nodes[id];
1283
1272
  set({
@@ -1307,36 +1296,66 @@ var createNodesSlice = (set, get) => ({
1307
1296
 
1308
1297
  // ../core/store/slices/permissions.ts
1309
1298
  init_react_import();
1310
- var import_react8 = require("react");
1299
+ var import_react7 = require("react");
1300
+
1301
+ // ../core/lib/flatten-data.ts
1302
+ init_react_import();
1303
+ var flattenData = (state, config) => {
1304
+ const data = [];
1305
+ walkTree(
1306
+ state,
1307
+ config,
1308
+ (content) => content,
1309
+ (item) => {
1310
+ data.push(item);
1311
+ return null;
1312
+ }
1313
+ );
1314
+ return data;
1315
+ };
1316
+
1317
+ // ../core/lib/get-changed.ts
1318
+ init_react_import();
1319
+ var getChanged = (newItem, oldItem) => {
1320
+ return newItem ? Object.keys(newItem.props || {}).reduce((acc, item) => {
1321
+ const newItemProps = (newItem == null ? void 0 : newItem.props) || {};
1322
+ const oldItemProps = (oldItem == null ? void 0 : oldItem.props) || {};
1323
+ return __spreadProps(__spreadValues({}, acc), {
1324
+ [item]: oldItemProps[item] !== newItemProps[item]
1325
+ });
1326
+ }, {}) : {};
1327
+ };
1328
+
1329
+ // ../core/store/slices/permissions.ts
1311
1330
  var createPermissionsSlice = (set, get) => {
1312
1331
  const resolvePermissions = (..._0) => __async(void 0, [..._0], function* (params = {}, force) {
1313
- const { state, permissions } = get();
1314
- const { cache: cache3, globalPermissions } = permissions;
1332
+ const { state, permissions, config } = get();
1333
+ const { cache: cache2, globalPermissions } = permissions;
1315
1334
  const resolveDataForItem = (item2, force2 = false) => __async(void 0, null, function* () {
1316
1335
  var _a, _b, _c;
1317
1336
  const {
1318
- config,
1337
+ config: config2,
1319
1338
  state: appState,
1320
1339
  setComponentLoading,
1321
1340
  unsetComponentLoading
1322
1341
  } = get();
1323
- const componentConfig = item2.type === "root" ? config.root : config.components[item2.type];
1342
+ const componentConfig = item2.type === "root" ? config2.root : config2.components[item2.type];
1324
1343
  if (!componentConfig) {
1325
1344
  return;
1326
1345
  }
1327
1346
  const initialPermissions = __spreadValues(__spreadValues({}, globalPermissions), componentConfig.permissions);
1328
1347
  if (componentConfig.resolvePermissions) {
1329
- const changed = getChanged(item2, (_a = cache3[item2.props.id]) == null ? void 0 : _a.lastData);
1348
+ const changed = getChanged(item2, (_a = cache2[item2.props.id]) == null ? void 0 : _a.lastData);
1330
1349
  if (Object.values(changed).some((el) => el === true) || force2) {
1331
1350
  setComponentLoading(item2.props.id);
1332
1351
  const resolvedPermissions = yield componentConfig.resolvePermissions(
1333
1352
  item2,
1334
1353
  {
1335
1354
  changed,
1336
- lastPermissions: ((_b = cache3[item2.props.id]) == null ? void 0 : _b.lastPermissions) || null,
1355
+ lastPermissions: ((_b = cache2[item2.props.id]) == null ? void 0 : _b.lastPermissions) || null,
1337
1356
  permissions: initialPermissions,
1338
1357
  appState,
1339
- lastData: ((_c = cache3[item2.props.id]) == null ? void 0 : _c.lastData) || null
1358
+ lastData: ((_c = cache2[item2.props.id]) == null ? void 0 : _c.lastData) || null
1340
1359
  }
1341
1360
  );
1342
1361
  const latest = get().permissions;
@@ -1372,14 +1391,14 @@ var createPermissionsSlice = (set, get) => {
1372
1391
  if (item) {
1373
1392
  yield resolveDataForItem(item, force);
1374
1393
  } else if (type) {
1375
- flattenData(state.data).filter((item2) => item2.type === type).map((item2) => __async(void 0, null, function* () {
1394
+ flattenData(state, config).filter((item2) => item2.type === type).map((item2) => __async(void 0, null, function* () {
1376
1395
  yield resolveDataForItem(item2, force);
1377
1396
  }));
1378
1397
  } else if (root) {
1379
1398
  resolveDataForRoot(force);
1380
1399
  } else {
1381
1400
  resolveDataForRoot(force);
1382
- flattenData(state.data).map((item2) => __async(void 0, null, function* () {
1401
+ flattenData(state, config).map((item2) => __async(void 0, null, function* () {
1383
1402
  yield resolveDataForItem(item2, force);
1384
1403
  }));
1385
1404
  }
@@ -1421,8 +1440,8 @@ var createPermissionsSlice = (set, get) => {
1421
1440
 
1422
1441
  // ../core/store/slices/fields.ts
1423
1442
  init_react_import();
1424
- var import_react9 = require("react");
1425
- var createFieldsStore = (_set, _get) => {
1443
+ var import_react8 = require("react");
1444
+ var createFieldsSlice = (_set, _get) => {
1426
1445
  return {
1427
1446
  fields: {},
1428
1447
  loading: false,
@@ -1430,6 +1449,111 @@ var createFieldsStore = (_set, _get) => {
1430
1449
  };
1431
1450
  };
1432
1451
 
1452
+ // ../core/lib/resolve-component-data.ts
1453
+ init_react_import();
1454
+
1455
+ // ../core/lib/map-slots.ts
1456
+ init_react_import();
1457
+ function mapSlots(item, map, recursive = true, isSlot2) {
1458
+ return __async(this, null, function* () {
1459
+ const props = __spreadValues({}, item.props);
1460
+ yield forEachSlot(
1461
+ item,
1462
+ (_parentId, propName, content) => __async(this, null, function* () {
1463
+ const mappedContent = recursive ? yield Promise.all(
1464
+ content.map((item2) => __async(this, null, function* () {
1465
+ return yield mapSlots(item2, map, recursive, isSlot2);
1466
+ }))
1467
+ ) : content;
1468
+ props[propName] = yield map(mappedContent, propName);
1469
+ }),
1470
+ false,
1471
+ isSlot2
1472
+ );
1473
+ return __spreadProps(__spreadValues({}, item), { props });
1474
+ });
1475
+ }
1476
+
1477
+ // ../core/lib/resolve-component-data.ts
1478
+ var import_fast_deep_equal = __toESM(require_fast_deep_equal());
1479
+ var cache = { lastChange: {} };
1480
+ var resolveComponentData = (_0, _1, ..._2) => __async(void 0, [_0, _1, ..._2], function* (item, config, metadata = {}, onResolveStart, onResolveEnd, trigger = "replace", recursive = true) {
1481
+ const configForItem = "type" in item && item.type !== "root" ? config.components[item.type] : config.root;
1482
+ if ((configForItem == null ? void 0 : configForItem.resolveData) && item.props) {
1483
+ const id = "id" in item.props ? item.props.id : "root";
1484
+ const { item: oldItem = null, resolved = {} } = cache.lastChange[id] || {};
1485
+ if (item && (0, import_fast_deep_equal.default)(item, oldItem)) {
1486
+ return { node: resolved, didChange: false };
1487
+ }
1488
+ const changed = getChanged(item, oldItem);
1489
+ if (onResolveStart) {
1490
+ onResolveStart(item);
1491
+ }
1492
+ const { props: resolvedProps, readOnly = {} } = yield configForItem.resolveData(item, {
1493
+ changed,
1494
+ lastData: oldItem,
1495
+ metadata,
1496
+ trigger
1497
+ });
1498
+ let resolvedItem = __spreadProps(__spreadValues({}, item), {
1499
+ props: __spreadValues(__spreadValues({}, item.props), resolvedProps)
1500
+ });
1501
+ if (recursive) {
1502
+ resolvedItem = yield mapSlots(
1503
+ resolvedItem,
1504
+ (content) => __async(void 0, null, function* () {
1505
+ return Promise.all(
1506
+ content.map(
1507
+ (childItem) => __async(void 0, null, function* () {
1508
+ return (yield resolveComponentData(
1509
+ childItem,
1510
+ config,
1511
+ metadata,
1512
+ onResolveStart,
1513
+ onResolveEnd,
1514
+ trigger,
1515
+ false
1516
+ )).node;
1517
+ })
1518
+ )
1519
+ );
1520
+ }),
1521
+ false,
1522
+ createIsSlotConfig(config)
1523
+ );
1524
+ }
1525
+ if (Object.keys(readOnly).length) {
1526
+ resolvedItem.readOnly = readOnly;
1527
+ }
1528
+ cache.lastChange[id] = {
1529
+ item,
1530
+ resolved: resolvedItem
1531
+ };
1532
+ if (onResolveEnd) {
1533
+ onResolveEnd(resolvedItem);
1534
+ }
1535
+ return { node: resolvedItem, didChange: !(0, import_fast_deep_equal.default)(item, resolvedItem) };
1536
+ }
1537
+ return { node: item, didChange: false };
1538
+ });
1539
+
1540
+ // ../core/lib/to-root.ts
1541
+ init_react_import();
1542
+ var toRoot = (item) => {
1543
+ if ("type" in item && item.type !== "root") {
1544
+ throw new Error("Converting non-root item to root.");
1545
+ }
1546
+ const { readOnly } = item;
1547
+ if (item.props) {
1548
+ if ("id" in item.props) {
1549
+ const _a = item.props, { id } = _a, props = __objRest(_a, ["id"]);
1550
+ return { props, readOnly };
1551
+ }
1552
+ return { props: item.props, readOnly };
1553
+ }
1554
+ return { props: {}, readOnly };
1555
+ };
1556
+
1433
1557
  // ../core/store/index.ts
1434
1558
  var defaultAppState = {
1435
1559
  data: { content: [], root: {}, zones: {} },
@@ -1450,6 +1574,10 @@ var defaultAppState = {
1450
1574
  controlsVisible: true
1451
1575
  },
1452
1576
  field: { focus: null }
1577
+ },
1578
+ indexes: {
1579
+ nodes: {},
1580
+ zones: {}
1453
1581
  }
1454
1582
  };
1455
1583
  var defaultPageFields = {
@@ -1472,7 +1600,7 @@ var createAppStore = (initialAppStore) => create()(
1472
1600
  iframe: {},
1473
1601
  metadata: {}
1474
1602
  }, initialAppStore), {
1475
- fields: createFieldsStore(set, get),
1603
+ fields: createFieldsSlice(set, get),
1476
1604
  history: createHistorySlice(set, get),
1477
1605
  nodes: createNodesSlice(set, get),
1478
1606
  permissions: createPermissionsSlice(set, get),
@@ -1485,65 +1613,145 @@ var createAppStore = (initialAppStore) => create()(
1485
1613
  dispatch: (action) => set((s) => {
1486
1614
  var _a, _b;
1487
1615
  const { record } = get().history;
1488
- const dispatch = createReducer({ config: s.config, record });
1616
+ const dispatch = createReducer({
1617
+ record,
1618
+ appStore: s
1619
+ });
1489
1620
  const state = dispatch(s.state, action);
1490
- const selectedItem = state.ui.itemSelector ? getItem(state.ui.itemSelector, state.data) : null;
1621
+ const selectedItem = state.ui.itemSelector ? getItem(state.ui.itemSelector, state) : null;
1491
1622
  (_b = (_a = get()).onAction) == null ? void 0 : _b.call(_a, action, state, get().state);
1492
1623
  return __spreadProps(__spreadValues({}, s), { state, selectedItem });
1493
1624
  }),
1494
1625
  setZoomConfig: (zoomConfig) => set({ zoomConfig }),
1495
1626
  setStatus: (status) => set({ status }),
1496
1627
  setComponentState: (componentState) => set({ componentState }),
1497
- setComponentLoading: (id) => {
1498
- var _a;
1499
- const { setComponentState, componentState } = get();
1500
- setComponentState(__spreadProps(__spreadValues({}, componentState), {
1501
- [id]: __spreadProps(__spreadValues({}, componentState[id]), {
1502
- loadingCount: (((_a = componentState[id]) == null ? void 0 : _a.loadingCount) || 0) + 1
1628
+ pendingComponentLoads: {},
1629
+ setComponentLoading: (id, loading = true, defer = 0) => {
1630
+ const { setComponentState, pendingComponentLoads } = get();
1631
+ const thisPendingComponentLoads = __spreadValues({}, pendingComponentLoads);
1632
+ const setLoading = () => {
1633
+ var _a;
1634
+ const { componentState } = get();
1635
+ setComponentState(__spreadProps(__spreadValues({}, componentState), {
1636
+ [id]: __spreadProps(__spreadValues({}, componentState[id]), {
1637
+ loadingCount: (((_a = componentState[id]) == null ? void 0 : _a.loadingCount) || 0) + 1
1638
+ })
1639
+ }));
1640
+ };
1641
+ const unsetLoading = () => {
1642
+ var _a;
1643
+ const { componentState } = get();
1644
+ setComponentState(__spreadProps(__spreadValues({}, componentState), {
1645
+ [id]: __spreadProps(__spreadValues({}, componentState[id]), {
1646
+ loadingCount: Math.max(
1647
+ (((_a = componentState[id]) == null ? void 0 : _a.loadingCount) || 0) - 1,
1648
+ 0
1649
+ )
1650
+ })
1651
+ }));
1652
+ };
1653
+ if (thisPendingComponentLoads[id]) {
1654
+ clearTimeout(thisPendingComponentLoads[id]);
1655
+ delete thisPendingComponentLoads[id];
1656
+ set({ pendingComponentLoads: thisPendingComponentLoads });
1657
+ }
1658
+ const timeout = setTimeout(() => {
1659
+ if (loading) {
1660
+ setLoading();
1661
+ } else {
1662
+ unsetLoading();
1663
+ }
1664
+ delete thisPendingComponentLoads[id];
1665
+ set({ pendingComponentLoads: thisPendingComponentLoads });
1666
+ }, defer);
1667
+ set({
1668
+ pendingComponentLoads: __spreadProps(__spreadValues({}, thisPendingComponentLoads), {
1669
+ [id]: timeout
1503
1670
  })
1504
- }));
1671
+ });
1505
1672
  },
1506
1673
  unsetComponentLoading: (id) => {
1507
- var _a;
1508
- const { setComponentState, componentState } = get();
1509
- setComponentState(__spreadProps(__spreadValues({}, componentState), {
1510
- [id]: __spreadProps(__spreadValues({}, componentState[id]), {
1511
- loadingCount: Math.max(
1512
- (((_a = componentState[id]) == null ? void 0 : _a.loadingCount) || 0) - 1,
1513
- 0
1514
- )
1515
- })
1516
- }));
1674
+ const { setComponentLoading } = get();
1675
+ setComponentLoading(id, false);
1517
1676
  },
1518
1677
  // Helper
1519
1678
  setUi: (ui, recordHistory) => set((s) => {
1520
1679
  const dispatch = createReducer({
1521
- config: s.config,
1522
1680
  record: () => {
1523
- }
1681
+ },
1682
+ appStore: s
1524
1683
  });
1525
1684
  const state = dispatch(s.state, {
1526
1685
  type: "setUi",
1527
1686
  ui,
1528
1687
  recordHistory
1529
1688
  });
1530
- const selectedItem = state.ui.itemSelector ? getItem(state.ui.itemSelector, state.data) : null;
1689
+ const selectedItem = state.ui.itemSelector ? getItem(state.ui.itemSelector, state) : null;
1531
1690
  return __spreadProps(__spreadValues({}, s), { state, selectedItem });
1532
1691
  }),
1533
- resolveDataRuns: 0,
1534
- resolveData: (newAppState) => set((s) => {
1535
- resolveData(newAppState, get());
1536
- return __spreadProps(__spreadValues({}, s), { resolveDataRuns: s.resolveDataRuns + 1 });
1692
+ resolveComponentData: (componentData, trigger) => __async(void 0, null, function* () {
1693
+ const { config, metadata, setComponentLoading } = get();
1694
+ return yield resolveComponentData(
1695
+ componentData,
1696
+ config,
1697
+ metadata,
1698
+ (item) => setComponentLoading(
1699
+ "id" in item.props ? item.props.id : "root",
1700
+ true,
1701
+ 50
1702
+ ),
1703
+ (item) => setComponentLoading(
1704
+ "id" in item.props ? item.props.id : "root",
1705
+ false,
1706
+ 0
1707
+ ),
1708
+ trigger
1709
+ );
1710
+ }),
1711
+ resolveAndCommitData: () => __async(void 0, null, function* () {
1712
+ const { config, state, dispatch, resolveComponentData: resolveComponentData2 } = get();
1713
+ walkTree(
1714
+ state,
1715
+ config,
1716
+ (content) => content,
1717
+ (childItem) => {
1718
+ resolveComponentData2(childItem, "load").then((resolved) => {
1719
+ const { state: state2 } = get();
1720
+ const node = state2.indexes.nodes[resolved.node.props.id];
1721
+ if (node && resolved.didChange) {
1722
+ if (resolved.node.props.id === "root") {
1723
+ dispatch({
1724
+ type: "replaceRoot",
1725
+ root: toRoot(resolved.node)
1726
+ });
1727
+ } else {
1728
+ const zoneCompound = `${node.parentId}:${node.zone}`;
1729
+ const parentZone = state2.indexes.zones[zoneCompound];
1730
+ const index = parentZone.contentIds.indexOf(
1731
+ resolved.node.props.id
1732
+ );
1733
+ dispatch({
1734
+ type: "replace",
1735
+ data: resolved.node,
1736
+ destinationIndex: index,
1737
+ destinationZone: zoneCompound
1738
+ });
1739
+ }
1740
+ }
1741
+ });
1742
+ return childItem;
1743
+ }
1744
+ );
1537
1745
  })
1538
1746
  }))
1539
1747
  );
1540
- var appStoreContext = (0, import_react10.createContext)(createAppStore());
1748
+ var appStoreContext = (0, import_react9.createContext)(createAppStore());
1541
1749
  function useAppStore(selector) {
1542
- const context = (0, import_react10.useContext)(appStoreContext);
1750
+ const context = (0, import_react9.useContext)(appStoreContext);
1543
1751
  return useStore(context, selector);
1544
1752
  }
1545
1753
  function useAppStoreApi() {
1546
- return (0, import_react10.useContext)(appStoreContext);
1754
+ return (0, import_react9.useContext)(appStoreContext);
1547
1755
  }
1548
1756
 
1549
1757
  // ../core/lib/use-breadcrumbs.ts
@@ -1555,12 +1763,12 @@ var useBreadcrumbs = (renderCount) => {
1555
1763
  const config = useAppStore((s) => s.config);
1556
1764
  const path = useAppStore((s) => {
1557
1765
  var _a;
1558
- return (_a = s.nodes.nodes[selectedId]) == null ? void 0 : _a.path;
1766
+ return (_a = s.state.indexes.nodes[selectedId]) == null ? void 0 : _a.path;
1559
1767
  });
1560
1768
  const appStore = useAppStoreApi();
1561
- return (0, import_react11.useMemo)(() => {
1769
+ return (0, import_react10.useMemo)(() => {
1562
1770
  const breadcrumbs = (path == null ? void 0 : path.map((zoneCompound) => {
1563
- var _a, _b;
1771
+ var _a, _b, _c;
1564
1772
  const [componentId] = zoneCompound.split(":");
1565
1773
  if (componentId === "root") {
1566
1774
  return {
@@ -1568,12 +1776,15 @@ var useBreadcrumbs = (renderCount) => {
1568
1776
  selector: null
1569
1777
  };
1570
1778
  }
1571
- const node = appStore.getState().nodes.nodes[componentId];
1572
- const label = node ? (_b = (_a = config.components[node.data.type]) == null ? void 0 : _a.label) != null ? _b : node.data.type : "Component";
1779
+ const node = appStore.getState().state.indexes.nodes[componentId];
1780
+ const parentId = node.path[node.path.length - 1];
1781
+ const contentIds = ((_a = appStore.getState().state.indexes.zones[parentId]) == null ? void 0 : _a.contentIds) || [];
1782
+ const index = contentIds.indexOf(componentId);
1783
+ const label = node ? (_c = (_b = config.components[node.data.type]) == null ? void 0 : _b.label) != null ? _c : node.data.type : "Component";
1573
1784
  return {
1574
1785
  label,
1575
1786
  selector: node ? {
1576
- index: node.index,
1787
+ index,
1577
1788
  zone: node.path[node.path.length - 1]
1578
1789
  } : null
1579
1790
  };
@@ -1594,6 +1805,12 @@ init_react_import();
1594
1805
  // ../core/lib/filter.ts
1595
1806
  init_react_import();
1596
1807
 
1808
+ // ../core/lib/reorder.ts
1809
+ init_react_import();
1810
+
1811
+ // ../core/lib/replace.ts
1812
+ init_react_import();
1813
+
1597
1814
  // css-module:/home/runner/work/puck/puck/packages/core/components/Loader/styles.module.css#css-module
1598
1815
  init_react_import();
1599
1816
  var styles_module_default3 = { "Loader": "_Loader_nacdm_13", "loader-animation": "_loader-animation_nacdm_1" };
@@ -1774,8 +1991,8 @@ function buildHierarchy(frame) {
1774
1991
  var usePuck = (0, import_puck.createUsePuck)();
1775
1992
  var HeadingAnalyzer = () => {
1776
1993
  const data = usePuck((s) => s.appState.data);
1777
- const [hierarchy, setHierarchy] = (0, import_react12.useState)([]);
1778
- (0, import_react12.useEffect)(() => {
1994
+ const [hierarchy, setHierarchy] = (0, import_react11.useState)([]);
1995
+ (0, import_react11.useEffect)(() => {
1779
1996
  const frame = getFrame();
1780
1997
  const entry = frame == null ? void 0 : frame.querySelector(`[data-puck-entry]`);
1781
1998
  if (!entry) return;