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