@measured/puck-plugin-heading-analyzer 0.19.0-canary.0ab653c → 0.19.0-canary.1918ad70

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,43 @@ 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
+
494
+ // ../core/lib/for-each-slot.ts
495
+ var forEachSlot = (_0, _1, ..._2) => __async(void 0, [_0, _1, ..._2], function* (item, cb, recursive = false, isSlot2 = isSlot) {
496
+ const props = item.props || {};
497
+ const propKeys = Object.keys(props);
498
+ for (let i = 0; i < propKeys.length; i++) {
499
+ const propKey = propKeys[i];
500
+ const itemType = "type" in item ? item.type : "root";
501
+ if (isSlot2(itemType, propKey, props[propKey])) {
502
+ const content = props[propKey];
503
+ yield cb(props.id, propKey, content);
504
+ if (recursive) {
505
+ content.forEach(
506
+ (childItem) => __async(void 0, null, function* () {
507
+ return yield forEachSlot(childItem, cb, true, isSlot2);
508
+ })
509
+ );
510
+ }
511
+ }
512
+ }
513
+ });
514
+
515
+ // ../core/lib/for-related-zones.ts
516
+ init_react_import();
517
+
503
518
  // ../core/lib/get-zone-id.ts
504
519
  init_react_import();
505
520
  var getZoneId = (zoneCompound) => {
@@ -512,302 +527,489 @@ var getZoneId = (zoneCompound) => {
512
527
  return [rootDroppableId, zoneCompound];
513
528
  };
514
529
 
515
- // ../core/lib/reduce-related-zones.ts
516
- function reduceRelatedZones(item, data, fn) {
530
+ // ../core/lib/for-related-zones.ts
531
+ function forRelatedZones(item, data, cb, path = []) {
532
+ Object.entries(data.zones || {}).forEach(([zoneCompound, content]) => {
533
+ const [parentId] = getZoneId(zoneCompound);
534
+ if (parentId === item.props.id) {
535
+ const newPath = [...path, zoneCompound];
536
+ content.forEach((item2) => forRelatedZones(item2, data, cb, newPath));
537
+ cb(path, zoneCompound, content);
538
+ }
539
+ });
540
+ }
541
+
542
+ // ../core/lib/strip-slots.ts
543
+ init_react_import();
544
+ var stripSlots = (data) => {
517
545
  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]);
546
+ props: Object.entries(data.props).reduce(
547
+ (acc, [propKey, propVal]) => {
548
+ if (isSlot(propVal)) {
549
+ return acc;
524
550
  }
525
- return __spreadProps(__spreadValues({}, acc), { [key]: data.zones[key] });
551
+ return __spreadProps(__spreadValues({}, acc), { [propKey]: propVal });
526
552
  },
527
- {}
553
+ { id: data.props.id }
528
554
  )
529
555
  });
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
556
  };
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
- });
557
+
558
+ // ../core/lib/walk-tree.ts
559
+ function walkTree(state, config, mapContent = (content) => content, mapNodeOrSkip = (item) => item) {
560
+ var _a;
561
+ let newZones = {};
562
+ const newZoneIndex = {};
563
+ const newNodeIndex = {};
564
+ const processContent = (path, zoneCompound, content, zoneType, newId) => {
565
+ var _a2;
566
+ const [parentId] = zoneCompound.split(":");
567
+ const mappedContent = ((_a2 = mapContent(content, zoneCompound, zoneType)) != null ? _a2 : content) || [];
568
+ const [_2, zone] = zoneCompound.split(":");
569
+ const newZoneCompound = `${newId || parentId}:${zone}`;
570
+ const newContent2 = mappedContent.map(
571
+ (zoneChild, index) => processItem(zoneChild, [...path, newZoneCompound], index)
572
+ );
573
+ newZoneIndex[newZoneCompound] = {
574
+ contentIds: newContent2.map((item) => item.props.id),
575
+ type: zoneType
576
+ };
577
+ return [newZoneCompound, newContent2];
578
+ };
579
+ const processRelatedZones = (item, newId, initialPath) => {
580
+ forRelatedZones(
581
+ item,
582
+ state.data,
583
+ (relatedPath, relatedZoneCompound, relatedContent) => {
584
+ const [zoneCompound, newContent2] = processContent(
585
+ relatedPath,
586
+ relatedZoneCompound,
587
+ relatedContent,
588
+ "dropzone",
589
+ newId
590
+ );
591
+ newZones[zoneCompound] = newContent2;
592
+ },
593
+ initialPath
594
+ );
595
+ };
596
+ const processItem = (item, path, index) => {
597
+ const mappedItem = mapNodeOrSkip(item, path, index);
598
+ if (!mappedItem) return item;
599
+ const id = mappedItem.props.id;
600
+ processRelatedZones(item, id, path);
601
+ const newProps = __spreadValues({}, mappedItem.props);
602
+ forEachSlot(
603
+ mappedItem,
604
+ (parentId2, slotId, content) => {
605
+ const zoneCompound = `${parentId2}:${slotId}`;
606
+ const [_2, newContent2] = processContent(
607
+ path,
608
+ zoneCompound,
609
+ content,
610
+ "slot",
611
+ parentId2
612
+ );
613
+ newProps[slotId] = newContent2;
614
+ },
615
+ false,
616
+ (itemType, propName, propValue) => {
617
+ var _a2, _b;
618
+ const configForComponent = itemType === "root" ? config == null ? void 0 : config.root : config == null ? void 0 : config.components[itemType];
619
+ if (!configForComponent) return isSlot(propValue);
620
+ return ((_b = (_a2 = configForComponent.fields) == null ? void 0 : _a2[propName]) == null ? void 0 : _b.type) === "slot";
553
621
  }
554
- return acc;
622
+ );
623
+ const newItem = __spreadProps(__spreadValues({}, item), { props: newProps });
624
+ const thisZoneCompound = path[path.length - 1];
625
+ const [parentId, zone] = thisZoneCompound ? thisZoneCompound.split(":") : [null, ""];
626
+ newNodeIndex[id] = {
627
+ data: newItem,
628
+ flatData: stripSlots(newItem),
629
+ path,
630
+ parentId,
631
+ zone
632
+ };
633
+ const finalData = newItem;
634
+ if (newProps.id === "root") {
635
+ delete finalData["type"];
636
+ delete finalData.props["id"];
637
+ }
638
+ return finalData;
639
+ };
640
+ const zones = state.data.zones || {};
641
+ const [_, newContent] = processContent(
642
+ [],
643
+ rootDroppableId,
644
+ state.data.content,
645
+ "root"
646
+ );
647
+ const processedContent = newContent;
648
+ Object.keys(zones || {}).forEach((zoneCompound) => {
649
+ const [parentId] = zoneCompound.split(":");
650
+ const [_2, newContent2] = processContent(
651
+ [rootDroppableId],
652
+ zoneCompound,
653
+ zones[zoneCompound],
654
+ "dropzone",
655
+ parentId
656
+ );
657
+ newZones[zoneCompound] = newContent2;
658
+ }, newZones);
659
+ const processedRoot = processItem(
660
+ {
661
+ type: "root",
662
+ props: __spreadProps(__spreadValues({}, (_a = state.data.root.props) != null ? _a : state.data.root), { id: "root" })
555
663
  },
556
- {}
664
+ [],
665
+ -1
557
666
  );
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];
667
+ const root = __spreadProps(__spreadValues({}, state.data.root), {
668
+ props: processedRoot.props
564
669
  });
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
- });
670
+ return __spreadProps(__spreadValues({}, state), {
671
+ data: {
672
+ root,
673
+ // 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.
674
+ content: processedContent,
675
+ zones: __spreadValues(__spreadValues({}, state.data.zones), newZones)
676
+ },
677
+ indexes: {
678
+ nodes: __spreadValues(__spreadValues({}, state.indexes.nodes), newNodeIndex),
679
+ zones: __spreadValues(__spreadValues({}, state.indexes.zones), newZoneIndex)
680
+ }
581
681
  });
582
682
  }
583
683
 
584
- // ../core/reducer/data.ts
585
- 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)
684
+ // ../core/lib/deindex.ts
685
+ init_react_import();
686
+ var deindex = (state, componentData) => {
687
+ let zones = __spreadValues({}, state.indexes.zones);
688
+ let nodes = __spreadValues({}, state.indexes.nodes);
689
+ const dindexRelatedZones = (item) => {
690
+ forRelatedZones(item, state.data, (_path, zoneCompound, content) => {
691
+ content.forEach((subItem) => {
692
+ dindexChildren(subItem);
693
+ delete nodes[subItem.props.id];
694
+ });
695
+ delete zones[zoneCompound];
590
696
  });
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
- });
697
+ };
698
+ const dindexChildren = (item) => {
699
+ forEachSlot(
700
+ item,
701
+ (parentId, slotId, content) => {
702
+ const zoneCompound = `${parentId}:${slotId}`;
703
+ delete zones[zoneCompound];
704
+ content.forEach((item2) => {
705
+ dindexRelatedZones(item2);
706
+ delete nodes[item2.props.id];
707
+ });
708
+ },
709
+ true
710
+ );
711
+ };
712
+ dindexRelatedZones(componentData);
713
+ dindexChildren(componentData);
714
+ delete nodes[componentData.props.id];
715
+ return { nodes, zones };
716
+ };
717
+
718
+ // ../core/reducer/reduce.ts
719
+ var zoneCache = {};
720
+ var getIdsForParent = (zoneCompound, state) => {
721
+ const [parentId] = zoneCompound.split(":");
722
+ const node = state.indexes.nodes[parentId];
723
+ return ((node == null ? void 0 : node.path) || []).map((p) => p.split(":")[0]);
602
724
  };
603
- function insertAction(data, action, config) {
725
+ function insertAction(state, action, config) {
726
+ const id = action.id || generateId(action.componentType);
604
727
  const emptyComponentData = {
605
728
  type: action.componentType,
606
729
  props: __spreadProps(__spreadValues({}, config.components[action.componentType].defaultProps || {}), {
607
- id: action.id || generateId(action.componentType)
730
+ id
608
731
  })
609
732
  };
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
- });
733
+ const [parentId] = action.destinationZone.split(":");
734
+ const idsInPath = getIdsForParent(action.destinationZone, state);
735
+ return walkTree(
736
+ state,
737
+ config,
738
+ (content, zoneCompound) => {
739
+ if (zoneCompound === action.destinationZone) {
740
+ return insert(
741
+ content || [],
742
+ action.destinationIndex,
743
+ emptyComponentData
744
+ );
745
+ }
746
+ return content;
747
+ },
748
+ (childItem) => {
749
+ if (childItem.props.id === id || childItem.props.id === parentId) {
750
+ return childItem;
751
+ } else if (idsInPath.indexOf(childItem.props.id) > -1) {
752
+ return childItem;
753
+ }
754
+ return null;
755
+ }
756
+ );
629
757
  }
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
- });
758
+ var moveAction = (state, action, appStore) => {
759
+ if (action.sourceZone === action.destinationZone && action.sourceIndex === action.destinationIndex) {
760
+ return state;
639
761
  }
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
- })
649
- });
762
+ const item = getItem(
763
+ { zone: action.sourceZone, index: action.sourceIndex },
764
+ state
765
+ );
766
+ if (!item) return state;
767
+ const idsInSourcePath = getIdsForParent(action.sourceZone, state);
768
+ const idsInDestinationPath = getIdsForParent(action.destinationZone, state);
769
+ return walkTree(
770
+ state,
771
+ appStore.config,
772
+ (content, zoneCompound) => {
773
+ if (zoneCompound === action.sourceZone && zoneCompound === action.destinationZone) {
774
+ return insert(
775
+ remove(content, action.sourceIndex),
776
+ action.destinationIndex,
777
+ item
778
+ );
779
+ } else if (zoneCompound === action.sourceZone) {
780
+ return remove(content, action.sourceIndex);
781
+ } else if (zoneCompound === action.destinationZone) {
782
+ return insert(content, action.destinationIndex, item);
783
+ }
784
+ return content;
785
+ },
786
+ (childItem) => {
787
+ const [sourceZoneParent] = action.sourceZone.split(":");
788
+ const [destinationZoneParent] = action.destinationZone.split(":");
789
+ const childId = childItem.props.id;
790
+ if (sourceZoneParent === childId || destinationZoneParent === childId || item.props.id === childId || idsInSourcePath.indexOf(childId) > -1 || idsInDestinationPath.indexOf(childId) > -1) {
791
+ return childItem;
792
+ }
793
+ return null;
794
+ }
795
+ );
796
+ };
797
+ var replaceAction = (state, action, appStore) => {
798
+ const [parentId] = action.destinationZone.split(":");
799
+ const idsInPath = getIdsForParent(action.destinationZone, state);
800
+ return walkTree(
801
+ state,
802
+ appStore.config,
803
+ (content) => content,
804
+ (childItem, path) => {
805
+ const pathIds = path.map((p) => p.split(":")[0]);
806
+ if (childItem.props.id === action.data.props.id) {
807
+ return action.data;
808
+ } else if (childItem.props.id === parentId) {
809
+ return childItem;
810
+ } else if (idsInPath.indexOf(childItem.props.id) > -1) {
811
+ return childItem;
812
+ } else if (pathIds.indexOf(action.data.props.id) > -1) {
813
+ return childItem;
814
+ }
815
+ return null;
816
+ }
817
+ );
818
+ };
819
+ var setAction = (state, action, appStore) => {
820
+ if (typeof action.state === "object") {
821
+ const newState = __spreadValues(__spreadValues({}, state), action.state);
822
+ if (action.state.indexes) {
823
+ console.warn(
824
+ "`set` is expensive and may cause unnecessary re-renders. Consider using a more atomic action instead."
825
+ );
826
+ return newState;
827
+ }
828
+ return walkTree(newState, appStore.config);
829
+ }
830
+ return __spreadValues(__spreadValues({}, state), action.state(state));
650
831
  };
651
- function reduceData(data, action, config) {
832
+ function reduce(state, action, appStore) {
833
+ if (action.type === "set") {
834
+ return setAction(state, action, appStore);
835
+ }
652
836
  if (action.type === "insert") {
653
- return insertAction(data, action, config);
837
+ return insertAction(state, action, appStore.config);
838
+ }
839
+ if (action.type === "replace") {
840
+ return replaceAction(state, action, appStore);
841
+ }
842
+ if (action.type === "replaceRoot") {
843
+ return walkTree(
844
+ state,
845
+ appStore.config,
846
+ (content) => content,
847
+ (childItem) => {
848
+ if (childItem.props.id === "root") {
849
+ return __spreadProps(__spreadValues({}, childItem), {
850
+ props: __spreadValues(__spreadValues({}, childItem.props), action.root.props),
851
+ readOnly: action.root.readOnly
852
+ });
853
+ }
854
+ return childItem;
855
+ }
856
+ );
654
857
  }
655
858
  if (action.type === "duplicate") {
656
859
  const item = getItem(
657
860
  { index: action.sourceIndex, zone: action.sourceZone },
658
- data
861
+ state
659
862
  );
863
+ const idsInPath = getIdsForParent(action.sourceZone, state);
660
864
  const newItem = __spreadProps(__spreadValues({}, item), {
661
865
  props: __spreadProps(__spreadValues({}, item.props), {
662
866
  id: generateId(item.type)
663
867
  })
664
868
  });
665
- const dataWithRelatedDuplicated = duplicateRelatedZones(
666
- item,
667
- data,
668
- newItem.props.id
869
+ const modified = walkTree(
870
+ state,
871
+ appStore.config,
872
+ (content, zoneCompound) => {
873
+ if (zoneCompound === action.sourceZone) {
874
+ return insert(content, action.sourceIndex + 1, item);
875
+ }
876
+ return content;
877
+ },
878
+ (childItem, path, index) => {
879
+ const zoneCompound = path[path.length - 1];
880
+ const parents = path.map((p) => p.split(":")[0]);
881
+ if (parents.indexOf(newItem.props.id) > -1) {
882
+ return __spreadProps(__spreadValues({}, childItem), {
883
+ props: __spreadProps(__spreadValues({}, childItem.props), {
884
+ id: generateId(childItem.type)
885
+ })
886
+ });
887
+ }
888
+ if (zoneCompound === action.sourceZone && index === action.sourceIndex + 1) {
889
+ return newItem;
890
+ }
891
+ const [sourceZoneParent] = action.sourceZone.split(":");
892
+ if (sourceZoneParent === childItem.props.id || idsInPath.indexOf(childItem.props.id) > -1) {
893
+ return childItem;
894
+ }
895
+ return null;
896
+ }
669
897
  );
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
- )
898
+ return __spreadProps(__spreadValues({}, modified), {
899
+ ui: __spreadProps(__spreadValues({}, modified.ui), {
900
+ itemSelector: {
901
+ index: action.sourceIndex + 1,
902
+ zone: action.sourceZone
903
+ }
682
904
  })
683
905
  });
684
906
  }
685
907
  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
908
+ return moveAction(
909
+ state,
910
+ {
911
+ type: "move",
912
+ sourceIndex: action.sourceIndex,
913
+ sourceZone: action.destinationZone,
914
+ destinationIndex: action.destinationIndex,
915
+ destinationZone: action.destinationZone
916
+ },
917
+ appStore
699
918
  );
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
919
  }
740
- if (action.type === "replace") {
741
- return replaceAction(data, action);
920
+ if (action.type === "move") {
921
+ return moveAction(state, action, appStore);
742
922
  }
743
923
  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
924
+ const item = getItem({ index: action.index, zone: action.zone }, state);
925
+ let deindexed = deindex(state, item);
926
+ const [parentId] = action.zone.split(":");
927
+ return walkTree(
928
+ __spreadProps(__spreadValues({}, state), { indexes: deindexed }),
929
+ appStore.config,
930
+ (content, zoneCompound) => {
931
+ if (zoneCompound === action.zone) {
932
+ return remove(content, action.index);
933
+ }
934
+ return content;
935
+ },
936
+ (childItem, path) => {
937
+ const parentIds = path.map((p) => p.split(":")[0]);
938
+ if (childItem.props.id === parentId || childItem.props.id === item.props.id || parentIds.indexOf(item.props.id) > -1) {
939
+ return childItem;
940
+ }
941
+ return null;
942
+ }
748
943
  );
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
- });
762
944
  }
763
945
  if (action.type === "registerZone") {
764
946
  if (zoneCache[action.zone]) {
765
- return __spreadProps(__spreadValues({}, data), {
766
- zones: __spreadProps(__spreadValues({}, data.zones), {
767
- [action.zone]: zoneCache[action.zone]
947
+ return __spreadProps(__spreadValues({}, state), {
948
+ data: __spreadProps(__spreadValues({}, state.data), {
949
+ zones: __spreadProps(__spreadValues({}, state.data.zones), {
950
+ [action.zone]: zoneCache[action.zone]
951
+ })
952
+ }),
953
+ indexes: __spreadProps(__spreadValues({}, state.indexes), {
954
+ zones: __spreadProps(__spreadValues({}, state.indexes.zones), {
955
+ [action.zone]: __spreadProps(__spreadValues({}, state.indexes.zones[action.zone]), {
956
+ contentIds: zoneCache[action.zone].map((item) => item.props.id),
957
+ type: "dropzone"
958
+ })
959
+ })
768
960
  })
769
961
  });
770
962
  }
771
- return setupZone(data, action.zone);
963
+ return __spreadProps(__spreadValues({}, state), { data: setupZone(state.data, action.zone) });
772
964
  }
773
965
  if (action.type === "unregisterZone") {
774
- const _zones = __spreadValues({}, data.zones || {});
966
+ const _zones = __spreadValues({}, state.data.zones || {});
967
+ const zoneIndex = __spreadValues({}, state.indexes.zones || {});
775
968
  if (_zones[action.zone]) {
776
969
  zoneCache[action.zone] = _zones[action.zone];
777
970
  delete _zones[action.zone];
778
971
  }
779
- return __spreadProps(__spreadValues({}, data), { zones: _zones });
972
+ delete zoneIndex[action.zone];
973
+ return __spreadProps(__spreadValues({}, state), {
974
+ data: __spreadProps(__spreadValues({}, state.data), {
975
+ zones: _zones
976
+ }),
977
+ indexes: __spreadProps(__spreadValues({}, state.indexes), {
978
+ zones: zoneIndex
979
+ })
980
+ });
780
981
  }
781
982
  if (action.type === "setData") {
782
983
  if (typeof action.data === "object") {
783
- return __spreadValues(__spreadValues({}, data), action.data);
984
+ console.warn(
985
+ "`setData` is expensive and may cause unnecessary re-renders. Consider using a more atomic action instead."
986
+ );
987
+ return walkTree(
988
+ __spreadProps(__spreadValues({}, state), {
989
+ data: __spreadValues(__spreadValues({}, state.data), action.data)
990
+ }),
991
+ appStore.config
992
+ );
784
993
  }
785
- return __spreadValues(__spreadValues({}, data), action.data(data));
994
+ return walkTree(
995
+ __spreadProps(__spreadValues({}, state), {
996
+ data: __spreadValues(__spreadValues({}, state.data), action.data(state.data))
997
+ }),
998
+ appStore.config
999
+ );
786
1000
  }
787
- return data;
788
- }
789
-
790
- // ../core/reducer/state.ts
791
- init_react_import();
792
- var reduceUi = (ui, action) => {
793
1001
  if (action.type === "setUi") {
794
1002
  if (typeof action.ui === "object") {
795
- return __spreadValues(__spreadValues({}, ui), action.ui);
1003
+ return __spreadProps(__spreadValues({}, state), {
1004
+ ui: __spreadValues(__spreadValues({}, state.ui), action.ui)
1005
+ });
796
1006
  }
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 }
1007
+ return __spreadProps(__spreadValues({}, state), {
1008
+ ui: __spreadValues(__spreadValues({}, state.ui), action.ui(state.ui))
802
1009
  });
803
1010
  }
804
- if (action.type === "remove") {
805
- return __spreadProps(__spreadValues({}, ui), {
806
- itemSelector: null
807
- });
808
- }
809
- return ui;
810
- };
1011
+ return state;
1012
+ }
811
1013
 
812
1014
  // ../core/reducer/actions.tsx
813
1015
  init_react_import();
@@ -830,25 +1032,15 @@ function storeInterceptor(reducer, record, onAction) {
830
1032
  return newAppState;
831
1033
  };
832
1034
  }
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
1035
  function createReducer({
840
- config,
841
1036
  record,
842
- onAction
1037
+ onAction,
1038
+ appStore
843
1039
  }) {
844
1040
  return storeInterceptor(
845
1041
  (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 };
1042
+ const result = reduce(state, action, appStore);
1043
+ return result;
852
1044
  },
853
1045
  record,
854
1046
  onAction
@@ -868,11 +1060,11 @@ init_react_import();
868
1060
  var createStoreImpl = (createState) => {
869
1061
  let state;
870
1062
  const listeners = /* @__PURE__ */ new Set();
871
- const setState = (partial, replace2) => {
1063
+ const setState = (partial, replace) => {
872
1064
  const nextState = typeof partial === "function" ? partial(state) : partial;
873
1065
  if (!Object.is(nextState, state)) {
874
1066
  const previousState = state;
875
- state = (replace2 != null ? replace2 : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState);
1067
+ state = (replace != null ? replace : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState);
876
1068
  listeners.forEach((listener) => listener(state, previousState));
877
1069
  }
878
1070
  };
@@ -936,208 +1128,8 @@ var subscribeWithSelectorImpl = (fn) => (set, get, api) => {
936
1128
  };
937
1129
  var subscribeWithSelector = subscribeWithSelectorImpl;
938
1130
 
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
1131
  // ../core/store/index.ts
1140
- var import_react10 = require("react");
1132
+ var import_react9 = require("react");
1141
1133
 
1142
1134
  // ../core/store/slices/history.ts
1143
1135
  init_react_import();
@@ -1253,31 +1245,14 @@ var createHistorySlice = (set, get) => {
1253
1245
 
1254
1246
  // ../core/store/slices/nodes.ts
1255
1247
  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
1248
  var createNodesSlice = (set, get) => ({
1266
1249
  nodes: {},
1267
1250
  registerNode: (id, node) => {
1268
1251
  const s = get().nodes;
1269
- if (s.nodes[id] && partialDeepEqual(node, s.nodes[id])) {
1270
- return;
1271
- }
1272
1252
  const emptyNode = {
1273
1253
  id,
1274
1254
  methods: { sync: () => null },
1275
- data: { props: { id }, type: "unknown" },
1276
- parentId: "",
1277
- zone: "",
1278
- path: [],
1279
- element: null,
1280
- index: -1
1255
+ element: null
1281
1256
  };
1282
1257
  const existingNode = s.nodes[id];
1283
1258
  set({
@@ -1307,36 +1282,66 @@ var createNodesSlice = (set, get) => ({
1307
1282
 
1308
1283
  // ../core/store/slices/permissions.ts
1309
1284
  init_react_import();
1310
- var import_react8 = require("react");
1285
+ var import_react7 = require("react");
1286
+
1287
+ // ../core/lib/flatten-data.ts
1288
+ init_react_import();
1289
+ var flattenData = (state, config) => {
1290
+ const data = [];
1291
+ walkTree(
1292
+ state,
1293
+ config,
1294
+ (content) => content,
1295
+ (item) => {
1296
+ data.push(item);
1297
+ return null;
1298
+ }
1299
+ );
1300
+ return data;
1301
+ };
1302
+
1303
+ // ../core/lib/get-changed.ts
1304
+ init_react_import();
1305
+ var getChanged = (newItem, oldItem) => {
1306
+ return newItem ? Object.keys(newItem.props || {}).reduce((acc, item) => {
1307
+ const newItemProps = (newItem == null ? void 0 : newItem.props) || {};
1308
+ const oldItemProps = (oldItem == null ? void 0 : oldItem.props) || {};
1309
+ return __spreadProps(__spreadValues({}, acc), {
1310
+ [item]: oldItemProps[item] !== newItemProps[item]
1311
+ });
1312
+ }, {}) : {};
1313
+ };
1314
+
1315
+ // ../core/store/slices/permissions.ts
1311
1316
  var createPermissionsSlice = (set, get) => {
1312
1317
  const resolvePermissions = (..._0) => __async(void 0, [..._0], function* (params = {}, force) {
1313
- const { state, permissions } = get();
1314
- const { cache: cache3, globalPermissions } = permissions;
1318
+ const { state, permissions, config } = get();
1319
+ const { cache: cache2, globalPermissions } = permissions;
1315
1320
  const resolveDataForItem = (item2, force2 = false) => __async(void 0, null, function* () {
1316
1321
  var _a, _b, _c;
1317
1322
  const {
1318
- config,
1323
+ config: config2,
1319
1324
  state: appState,
1320
1325
  setComponentLoading,
1321
1326
  unsetComponentLoading
1322
1327
  } = get();
1323
- const componentConfig = item2.type === "root" ? config.root : config.components[item2.type];
1328
+ const componentConfig = item2.type === "root" ? config2.root : config2.components[item2.type];
1324
1329
  if (!componentConfig) {
1325
1330
  return;
1326
1331
  }
1327
1332
  const initialPermissions = __spreadValues(__spreadValues({}, globalPermissions), componentConfig.permissions);
1328
1333
  if (componentConfig.resolvePermissions) {
1329
- const changed = getChanged(item2, (_a = cache3[item2.props.id]) == null ? void 0 : _a.lastData);
1334
+ const changed = getChanged(item2, (_a = cache2[item2.props.id]) == null ? void 0 : _a.lastData);
1330
1335
  if (Object.values(changed).some((el) => el === true) || force2) {
1331
1336
  setComponentLoading(item2.props.id);
1332
1337
  const resolvedPermissions = yield componentConfig.resolvePermissions(
1333
1338
  item2,
1334
1339
  {
1335
1340
  changed,
1336
- lastPermissions: ((_b = cache3[item2.props.id]) == null ? void 0 : _b.lastPermissions) || null,
1341
+ lastPermissions: ((_b = cache2[item2.props.id]) == null ? void 0 : _b.lastPermissions) || null,
1337
1342
  permissions: initialPermissions,
1338
1343
  appState,
1339
- lastData: ((_c = cache3[item2.props.id]) == null ? void 0 : _c.lastData) || null
1344
+ lastData: ((_c = cache2[item2.props.id]) == null ? void 0 : _c.lastData) || null
1340
1345
  }
1341
1346
  );
1342
1347
  const latest = get().permissions;
@@ -1372,14 +1377,14 @@ var createPermissionsSlice = (set, get) => {
1372
1377
  if (item) {
1373
1378
  yield resolveDataForItem(item, force);
1374
1379
  } else if (type) {
1375
- flattenData(state.data).filter((item2) => item2.type === type).map((item2) => __async(void 0, null, function* () {
1380
+ flattenData(state, config).filter((item2) => item2.type === type).map((item2) => __async(void 0, null, function* () {
1376
1381
  yield resolveDataForItem(item2, force);
1377
1382
  }));
1378
1383
  } else if (root) {
1379
1384
  resolveDataForRoot(force);
1380
1385
  } else {
1381
1386
  resolveDataForRoot(force);
1382
- flattenData(state.data).map((item2) => __async(void 0, null, function* () {
1387
+ flattenData(state, config).map((item2) => __async(void 0, null, function* () {
1383
1388
  yield resolveDataForItem(item2, force);
1384
1389
  }));
1385
1390
  }
@@ -1421,8 +1426,8 @@ var createPermissionsSlice = (set, get) => {
1421
1426
 
1422
1427
  // ../core/store/slices/fields.ts
1423
1428
  init_react_import();
1424
- var import_react9 = require("react");
1425
- var createFieldsStore = (_set, _get) => {
1429
+ var import_react8 = require("react");
1430
+ var createFieldsSlice = (_set, _get) => {
1426
1431
  return {
1427
1432
  fields: {},
1428
1433
  loading: false,
@@ -1430,6 +1435,106 @@ var createFieldsStore = (_set, _get) => {
1430
1435
  };
1431
1436
  };
1432
1437
 
1438
+ // ../core/lib/resolve-component-data.ts
1439
+ init_react_import();
1440
+
1441
+ // ../core/lib/map-slots.ts
1442
+ init_react_import();
1443
+ function mapSlots(item, map, recursive = true, isSlot2) {
1444
+ return __async(this, null, function* () {
1445
+ const props = __spreadValues({}, item.props);
1446
+ yield forEachSlot(
1447
+ item,
1448
+ (_parentId, propName, content) => __async(this, null, function* () {
1449
+ const mappedContent = recursive ? yield Promise.all(
1450
+ content.map((item2) => __async(this, null, function* () {
1451
+ return yield mapSlots(item2, map, recursive, isSlot2);
1452
+ }))
1453
+ ) : content;
1454
+ props[propName] = yield map(mappedContent, propName);
1455
+ }),
1456
+ false,
1457
+ isSlot2
1458
+ );
1459
+ return __spreadProps(__spreadValues({}, item), { props });
1460
+ });
1461
+ }
1462
+
1463
+ // ../core/lib/resolve-component-data.ts
1464
+ var import_fast_deep_equal = __toESM(require_fast_deep_equal());
1465
+ var cache = { lastChange: {} };
1466
+ var resolveComponentData = (_0, _1, ..._2) => __async(void 0, [_0, _1, ..._2], function* (item, config, metadata = {}, onResolveStart, onResolveEnd, trigger = "replace", recursive = true) {
1467
+ const configForItem = "type" in item ? config.components[item.type] : config.root;
1468
+ if ((configForItem == null ? void 0 : configForItem.resolveData) && item.props) {
1469
+ const id = "id" in item.props ? item.props.id : "root";
1470
+ const { item: oldItem = null, resolved = {} } = cache.lastChange[id] || {};
1471
+ if (item && item === oldItem) {
1472
+ return resolved;
1473
+ }
1474
+ const changed = getChanged(item, oldItem);
1475
+ if (onResolveStart) {
1476
+ onResolveStart(item);
1477
+ }
1478
+ const { props: resolvedProps, readOnly = {} } = yield configForItem.resolveData(item, {
1479
+ changed,
1480
+ lastData: oldItem,
1481
+ metadata,
1482
+ trigger
1483
+ });
1484
+ let resolvedItem = __spreadProps(__spreadValues({}, item), {
1485
+ props: __spreadValues(__spreadValues({}, item.props), resolvedProps)
1486
+ });
1487
+ if (recursive) {
1488
+ resolvedItem = yield mapSlots(resolvedItem, (content) => __async(void 0, null, function* () {
1489
+ return Promise.all(
1490
+ content.map(
1491
+ (childItem) => __async(void 0, null, function* () {
1492
+ return (yield resolveComponentData(
1493
+ childItem,
1494
+ config,
1495
+ metadata,
1496
+ onResolveStart,
1497
+ onResolveEnd,
1498
+ trigger,
1499
+ false
1500
+ )).node;
1501
+ })
1502
+ )
1503
+ );
1504
+ }));
1505
+ }
1506
+ if (Object.keys(readOnly).length) {
1507
+ resolvedItem.readOnly = readOnly;
1508
+ }
1509
+ cache.lastChange[id] = {
1510
+ item,
1511
+ resolved: resolvedItem
1512
+ };
1513
+ if (onResolveEnd) {
1514
+ onResolveEnd(resolvedItem);
1515
+ }
1516
+ return { node: resolvedItem, didChange: !(0, import_fast_deep_equal.default)(item, resolvedItem) };
1517
+ }
1518
+ return { node: item, didChange: false };
1519
+ });
1520
+
1521
+ // ../core/lib/to-root.ts
1522
+ init_react_import();
1523
+ var toRoot = (item) => {
1524
+ if ("type" in item && item.type !== "root") {
1525
+ throw new Error("Converting non-root item to root.");
1526
+ }
1527
+ const { readOnly } = item;
1528
+ if (item.props) {
1529
+ if ("id" in item.props) {
1530
+ const _a = item.props, { id } = _a, props = __objRest(_a, ["id"]);
1531
+ return { props, readOnly };
1532
+ }
1533
+ return { props: item.props, readOnly };
1534
+ }
1535
+ return { props: {}, readOnly };
1536
+ };
1537
+
1433
1538
  // ../core/store/index.ts
1434
1539
  var defaultAppState = {
1435
1540
  data: { content: [], root: {}, zones: {} },
@@ -1450,6 +1555,10 @@ var defaultAppState = {
1450
1555
  controlsVisible: true
1451
1556
  },
1452
1557
  field: { focus: null }
1558
+ },
1559
+ indexes: {
1560
+ nodes: {},
1561
+ zones: {}
1453
1562
  }
1454
1563
  };
1455
1564
  var defaultPageFields = {
@@ -1472,7 +1581,7 @@ var createAppStore = (initialAppStore) => create()(
1472
1581
  iframe: {},
1473
1582
  metadata: {}
1474
1583
  }, initialAppStore), {
1475
- fields: createFieldsStore(set, get),
1584
+ fields: createFieldsSlice(set, get),
1476
1585
  history: createHistorySlice(set, get),
1477
1586
  nodes: createNodesSlice(set, get),
1478
1587
  permissions: createPermissionsSlice(set, get),
@@ -1485,65 +1594,151 @@ var createAppStore = (initialAppStore) => create()(
1485
1594
  dispatch: (action) => set((s) => {
1486
1595
  var _a, _b;
1487
1596
  const { record } = get().history;
1488
- const dispatch = createReducer({ config: s.config, record });
1597
+ const dispatch = createReducer({
1598
+ record,
1599
+ appStore: s
1600
+ });
1489
1601
  const state = dispatch(s.state, action);
1490
- const selectedItem = state.ui.itemSelector ? getItem(state.ui.itemSelector, state.data) : null;
1602
+ const selectedItem = state.ui.itemSelector ? getItem(state.ui.itemSelector, state) : null;
1491
1603
  (_b = (_a = get()).onAction) == null ? void 0 : _b.call(_a, action, state, get().state);
1492
1604
  return __spreadProps(__spreadValues({}, s), { state, selectedItem });
1493
1605
  }),
1494
1606
  setZoomConfig: (zoomConfig) => set({ zoomConfig }),
1495
1607
  setStatus: (status) => set({ status }),
1496
1608
  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
1609
+ pendingComponentLoads: {},
1610
+ setComponentLoading: (id, loading = true, defer = 0) => {
1611
+ const { setComponentState, pendingComponentLoads } = get();
1612
+ const thisPendingComponentLoads = __spreadValues({}, pendingComponentLoads);
1613
+ const setLoading = () => {
1614
+ var _a;
1615
+ const { componentState } = get();
1616
+ setComponentState(__spreadProps(__spreadValues({}, componentState), {
1617
+ [id]: __spreadProps(__spreadValues({}, componentState[id]), {
1618
+ loadingCount: (((_a = componentState[id]) == null ? void 0 : _a.loadingCount) || 0) + 1
1619
+ })
1620
+ }));
1621
+ };
1622
+ const unsetLoading = () => {
1623
+ var _a;
1624
+ const { componentState } = get();
1625
+ setComponentState(__spreadProps(__spreadValues({}, componentState), {
1626
+ [id]: __spreadProps(__spreadValues({}, componentState[id]), {
1627
+ loadingCount: Math.max(
1628
+ (((_a = componentState[id]) == null ? void 0 : _a.loadingCount) || 0) - 1,
1629
+ 0
1630
+ )
1631
+ })
1632
+ }));
1633
+ };
1634
+ if (thisPendingComponentLoads[id]) {
1635
+ clearTimeout(thisPendingComponentLoads[id]);
1636
+ delete thisPendingComponentLoads[id];
1637
+ set({ pendingComponentLoads: thisPendingComponentLoads });
1638
+ }
1639
+ const timeout = setTimeout(() => {
1640
+ if (loading) {
1641
+ setLoading();
1642
+ } else {
1643
+ unsetLoading();
1644
+ }
1645
+ delete thisPendingComponentLoads[id];
1646
+ set({ pendingComponentLoads: thisPendingComponentLoads });
1647
+ }, defer);
1648
+ set({
1649
+ pendingComponentLoads: __spreadProps(__spreadValues({}, thisPendingComponentLoads), {
1650
+ [id]: timeout
1503
1651
  })
1504
- }));
1652
+ });
1505
1653
  },
1506
1654
  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
- }));
1655
+ const { setComponentLoading } = get();
1656
+ setComponentLoading(id, false);
1517
1657
  },
1518
1658
  // Helper
1519
1659
  setUi: (ui, recordHistory) => set((s) => {
1520
1660
  const dispatch = createReducer({
1521
- config: s.config,
1522
1661
  record: () => {
1523
- }
1662
+ },
1663
+ appStore: s
1524
1664
  });
1525
1665
  const state = dispatch(s.state, {
1526
1666
  type: "setUi",
1527
1667
  ui,
1528
1668
  recordHistory
1529
1669
  });
1530
- const selectedItem = state.ui.itemSelector ? getItem(state.ui.itemSelector, state.data) : null;
1670
+ const selectedItem = state.ui.itemSelector ? getItem(state.ui.itemSelector, state) : null;
1531
1671
  return __spreadProps(__spreadValues({}, s), { state, selectedItem });
1532
1672
  }),
1533
- resolveDataRuns: 0,
1534
- resolveData: (newAppState) => set((s) => {
1535
- resolveData(newAppState, get());
1536
- return __spreadProps(__spreadValues({}, s), { resolveDataRuns: s.resolveDataRuns + 1 });
1673
+ // resolveDataRuns: 0,
1674
+ // resolveData: (newAppState) =>
1675
+ // set((s) => {
1676
+ // resolveData(newAppState, get);
1677
+ // return { ...s, resolveDataRuns: s.resolveDataRuns + 1 };
1678
+ // }),
1679
+ resolveComponentData: (componentData, trigger) => __async(void 0, null, function* () {
1680
+ const { config, metadata, setComponentLoading } = get();
1681
+ return yield resolveComponentData(
1682
+ componentData,
1683
+ config,
1684
+ metadata,
1685
+ (item) => setComponentLoading(
1686
+ "id" in item.props ? item.props.id : "root",
1687
+ true,
1688
+ 50
1689
+ ),
1690
+ (item) => setComponentLoading(
1691
+ "id" in item.props ? item.props.id : "root",
1692
+ false,
1693
+ 0
1694
+ ),
1695
+ trigger
1696
+ );
1697
+ }),
1698
+ resolveAndCommitData: () => __async(void 0, null, function* () {
1699
+ const { config, state, dispatch, resolveComponentData: resolveComponentData2 } = get();
1700
+ walkTree(
1701
+ state,
1702
+ config,
1703
+ (content) => content,
1704
+ (childItem) => {
1705
+ resolveComponentData2(childItem, "load").then((resolved) => {
1706
+ const { state: state2 } = get();
1707
+ const node = state2.indexes.nodes[resolved.node.props.id];
1708
+ if (node && resolved.didChange) {
1709
+ if (resolved.node.props.id === "root") {
1710
+ dispatch({
1711
+ type: "replaceRoot",
1712
+ root: toRoot(resolved.node)
1713
+ });
1714
+ } else {
1715
+ const zoneCompound = `${node.parentId}:${node.zone}`;
1716
+ const parentZone = state2.indexes.zones[zoneCompound];
1717
+ const index = parentZone.contentIds.indexOf(
1718
+ resolved.node.props.id
1719
+ );
1720
+ dispatch({
1721
+ type: "replace",
1722
+ data: resolved.node,
1723
+ destinationIndex: index,
1724
+ destinationZone: zoneCompound
1725
+ });
1726
+ }
1727
+ }
1728
+ });
1729
+ return childItem;
1730
+ }
1731
+ );
1537
1732
  })
1538
1733
  }))
1539
1734
  );
1540
- var appStoreContext = (0, import_react10.createContext)(createAppStore());
1735
+ var appStoreContext = (0, import_react9.createContext)(createAppStore());
1541
1736
  function useAppStore(selector) {
1542
- const context = (0, import_react10.useContext)(appStoreContext);
1737
+ const context = (0, import_react9.useContext)(appStoreContext);
1543
1738
  return useStore(context, selector);
1544
1739
  }
1545
1740
  function useAppStoreApi() {
1546
- return (0, import_react10.useContext)(appStoreContext);
1741
+ return (0, import_react9.useContext)(appStoreContext);
1547
1742
  }
1548
1743
 
1549
1744
  // ../core/lib/use-breadcrumbs.ts
@@ -1555,12 +1750,12 @@ var useBreadcrumbs = (renderCount) => {
1555
1750
  const config = useAppStore((s) => s.config);
1556
1751
  const path = useAppStore((s) => {
1557
1752
  var _a;
1558
- return (_a = s.nodes.nodes[selectedId]) == null ? void 0 : _a.path;
1753
+ return (_a = s.state.indexes.nodes[selectedId]) == null ? void 0 : _a.path;
1559
1754
  });
1560
1755
  const appStore = useAppStoreApi();
1561
- return (0, import_react11.useMemo)(() => {
1756
+ return (0, import_react10.useMemo)(() => {
1562
1757
  const breadcrumbs = (path == null ? void 0 : path.map((zoneCompound) => {
1563
- var _a, _b;
1758
+ var _a, _b, _c;
1564
1759
  const [componentId] = zoneCompound.split(":");
1565
1760
  if (componentId === "root") {
1566
1761
  return {
@@ -1568,12 +1763,15 @@ var useBreadcrumbs = (renderCount) => {
1568
1763
  selector: null
1569
1764
  };
1570
1765
  }
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";
1766
+ const node = appStore.getState().state.indexes.nodes[componentId];
1767
+ const parentId = node.path[node.path.length - 1];
1768
+ const contentIds = ((_a = appStore.getState().state.indexes.zones[parentId]) == null ? void 0 : _a.contentIds) || [];
1769
+ const index = contentIds.indexOf(componentId);
1770
+ const label = node ? (_c = (_b = config.components[node.data.type]) == null ? void 0 : _b.label) != null ? _c : node.data.type : "Component";
1573
1771
  return {
1574
1772
  label,
1575
1773
  selector: node ? {
1576
- index: node.index,
1774
+ index,
1577
1775
  zone: node.path[node.path.length - 1]
1578
1776
  } : null
1579
1777
  };
@@ -1594,6 +1792,12 @@ init_react_import();
1594
1792
  // ../core/lib/filter.ts
1595
1793
  init_react_import();
1596
1794
 
1795
+ // ../core/lib/reorder.ts
1796
+ init_react_import();
1797
+
1798
+ // ../core/lib/replace.ts
1799
+ init_react_import();
1800
+
1597
1801
  // css-module:/home/runner/work/puck/puck/packages/core/components/Loader/styles.module.css#css-module
1598
1802
  init_react_import();
1599
1803
  var styles_module_default3 = { "Loader": "_Loader_nacdm_13", "loader-animation": "_loader-animation_nacdm_1" };
@@ -1774,8 +1978,8 @@ function buildHierarchy(frame) {
1774
1978
  var usePuck = (0, import_puck.createUsePuck)();
1775
1979
  var HeadingAnalyzer = () => {
1776
1980
  const data = usePuck((s) => s.appState.data);
1777
- const [hierarchy, setHierarchy] = (0, import_react12.useState)([]);
1778
- (0, import_react12.useEffect)(() => {
1981
+ const [hierarchy, setHierarchy] = (0, import_react11.useState)([]);
1982
+ (0, import_react11.useEffect)(() => {
1779
1983
  const frame = getFrame();
1780
1984
  const entry = frame == null ? void 0 : frame.querySelector(`[data-puck-entry]`);
1781
1985
  if (!entry) return;