@chaibuilder/sdk 2.0.0-beta.91 → 2.0.0-beta.93

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/core.cjs CHANGED
@@ -17,8 +17,8 @@ const reactIcons = require("@radix-ui/react-icons");
17
17
  const web = require("@react-hookz/web");
18
18
  const flagged = require("flagged");
19
19
  const runtime = require("@chaibuilder/runtime");
20
- const TreeModel = require("tree-model");
21
20
  const ChaiThemeFn = require("./ChaiThemeFn-DcE5RdLQ.cjs");
21
+ const TreeModel = require("tree-model");
22
22
  const reactHotkeysHook = require("react-hotkeys-hook");
23
23
  const lucideReact = require("lucide-react");
24
24
  const ReactQuill = require("react-quill");
@@ -586,6 +586,142 @@ const getDefaultStore = () => {
586
586
  const RESET = Symbol(
587
587
  ""
588
588
  );
589
+ const getCached$1 = (c, m, k) => (m.has(k) ? m : m.set(k, c())).get(k);
590
+ const cache1$2 = /* @__PURE__ */ new WeakMap();
591
+ const memo2$1 = (create, dep1, dep2) => {
592
+ const cache2 = getCached$1(() => /* @__PURE__ */ new WeakMap(), cache1$2, dep1);
593
+ return getCached$1(create, cache2, dep2);
594
+ };
595
+ const cacheKeyForEmptyKeyExtractor = {};
596
+ const isWritable = (atom2) => !!atom2.write;
597
+ const isFunction = (x) => typeof x === "function";
598
+ function splitAtom(arrAtom, keyExtractor) {
599
+ return memo2$1(
600
+ () => {
601
+ const mappingCache = /* @__PURE__ */ new WeakMap();
602
+ const getMapping = (arr, prev) => {
603
+ let mapping = mappingCache.get(arr);
604
+ if (mapping) {
605
+ return mapping;
606
+ }
607
+ const prevMapping = prev && mappingCache.get(prev);
608
+ const atomList = [];
609
+ const keyList = [];
610
+ arr.forEach((item, index) => {
611
+ const key = index;
612
+ keyList[index] = key;
613
+ const cachedAtom = prevMapping && prevMapping.atomList[prevMapping.keyList.indexOf(key)];
614
+ if (cachedAtom) {
615
+ atomList[index] = cachedAtom;
616
+ return;
617
+ }
618
+ const read = (get) => {
619
+ const prev2 = get(mappingAtom);
620
+ const currArr = get(arrAtom);
621
+ const mapping2 = getMapping(currArr, prev2 == null ? void 0 : prev2.arr);
622
+ const index2 = mapping2.keyList.indexOf(key);
623
+ if (index2 < 0 || index2 >= currArr.length) {
624
+ const prevItem = arr[getMapping(arr).keyList.indexOf(key)];
625
+ if (prevItem) {
626
+ return prevItem;
627
+ }
628
+ throw new Error("splitAtom: index out of bounds for read");
629
+ }
630
+ return currArr[index2];
631
+ };
632
+ const write = (get, set, update) => {
633
+ const prev2 = get(mappingAtom);
634
+ const arr2 = get(arrAtom);
635
+ const mapping2 = getMapping(arr2, prev2 == null ? void 0 : prev2.arr);
636
+ const index2 = mapping2.keyList.indexOf(key);
637
+ if (index2 < 0 || index2 >= arr2.length) {
638
+ throw new Error("splitAtom: index out of bounds for write");
639
+ }
640
+ const nextItem = isFunction(update) ? update(arr2[index2]) : update;
641
+ if (!Object.is(arr2[index2], nextItem)) {
642
+ set(arrAtom, [
643
+ ...arr2.slice(0, index2),
644
+ nextItem,
645
+ ...arr2.slice(index2 + 1)
646
+ ]);
647
+ }
648
+ };
649
+ atomList[index] = isWritable(arrAtom) ? atom(read, write) : atom(read);
650
+ });
651
+ if (prevMapping && prevMapping.keyList.length === keyList.length && prevMapping.keyList.every((x, i) => x === keyList[i])) {
652
+ mapping = prevMapping;
653
+ } else {
654
+ mapping = { arr, atomList, keyList };
655
+ }
656
+ mappingCache.set(arr, mapping);
657
+ return mapping;
658
+ };
659
+ const mappingAtom = atom((get) => {
660
+ const prev = get(mappingAtom);
661
+ const arr = get(arrAtom);
662
+ const mapping = getMapping(arr, prev == null ? void 0 : prev.arr);
663
+ return mapping;
664
+ });
665
+ mappingAtom.init = void 0;
666
+ const splittedAtom = isWritable(arrAtom) ? atom(
667
+ (get) => get(mappingAtom).atomList,
668
+ (get, set, action) => {
669
+ switch (action.type) {
670
+ case "remove": {
671
+ const index = get(splittedAtom).indexOf(action.atom);
672
+ if (index >= 0) {
673
+ const arr = get(arrAtom);
674
+ set(arrAtom, [
675
+ ...arr.slice(0, index),
676
+ ...arr.slice(index + 1)
677
+ ]);
678
+ }
679
+ break;
680
+ }
681
+ case "insert": {
682
+ const index = action.before ? get(splittedAtom).indexOf(action.before) : get(splittedAtom).length;
683
+ if (index >= 0) {
684
+ const arr = get(arrAtom);
685
+ set(arrAtom, [
686
+ ...arr.slice(0, index),
687
+ action.value,
688
+ ...arr.slice(index)
689
+ ]);
690
+ }
691
+ break;
692
+ }
693
+ case "move": {
694
+ const index1 = get(splittedAtom).indexOf(action.atom);
695
+ const index2 = action.before ? get(splittedAtom).indexOf(action.before) : get(splittedAtom).length;
696
+ if (index1 >= 0 && index2 >= 0) {
697
+ const arr = get(arrAtom);
698
+ if (index1 < index2) {
699
+ set(arrAtom, [
700
+ ...arr.slice(0, index1),
701
+ ...arr.slice(index1 + 1, index2),
702
+ arr[index1],
703
+ ...arr.slice(index2)
704
+ ]);
705
+ } else {
706
+ set(arrAtom, [
707
+ ...arr.slice(0, index2),
708
+ arr[index1],
709
+ ...arr.slice(index2, index1),
710
+ ...arr.slice(index1 + 1)
711
+ ]);
712
+ }
713
+ }
714
+ break;
715
+ }
716
+ }
717
+ }
718
+ ) : atom((get) => get(mappingAtom).atomList);
719
+ return splittedAtom;
720
+ },
721
+ arrAtom,
722
+ cacheKeyForEmptyKeyExtractor
723
+ );
724
+ }
589
725
  const isPromiseLike$1 = (x) => typeof (x == null ? void 0 : x.then) === "function";
590
726
  function createJSONStorage(getStringStorage = () => {
591
727
  try {
@@ -978,10 +1114,61 @@ __publicField(Frame, "defaultProps", {
978
1114
  initialContent: '<!DOCTYPE html><html><head></head><body><div class="frame-root"></div></body></html>'
979
1115
  });
980
1116
  const ChaiFrame = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(Frame, { ...props, forwardedRef: ref }));
1117
+ const canAcceptChildBlock = (parentType, childType) => {
1118
+ if (!parentType) return true;
1119
+ const blockDefinition = runtime.getRegisteredChaiBlock(parentType);
1120
+ if (!blockDefinition) return false;
1121
+ return lodashEs.has(blockDefinition, "canAcceptBlock") ? blockDefinition.canAcceptBlock(childType) : false;
1122
+ };
1123
+ const canAddChildBlock = (parentType) => {
1124
+ const blockDefinition = runtime.getRegisteredChaiBlock(parentType);
1125
+ if (!blockDefinition) return false;
1126
+ return lodashEs.has(blockDefinition, "canAcceptBlock");
1127
+ };
1128
+ const canBeNestedInside = (parentType, childType) => {
1129
+ const blockDefinition = runtime.getRegisteredChaiBlock(childType);
1130
+ if (!blockDefinition) return true;
1131
+ return lodashEs.has(blockDefinition, "canBeNested") ? blockDefinition.canBeNested(parentType) : true;
1132
+ };
1133
+ const canDuplicateBlock = (type) => {
1134
+ const blockDefinition = runtime.getRegisteredChaiBlock(type);
1135
+ if (!blockDefinition) return true;
1136
+ return lodashEs.has(blockDefinition, "canDuplicate") ? blockDefinition.canDuplicate() : true;
1137
+ };
1138
+ const canDeleteBlock = (type) => {
1139
+ const blockDefinition = runtime.getRegisteredChaiBlock(type);
1140
+ if (!blockDefinition) return true;
1141
+ return lodashEs.has(blockDefinition, "canDelete") ? blockDefinition.canDelete() : true;
1142
+ };
1143
+ const canDropBlock = (_currentTree, { dragSource, dropTarget: dropTarget2 }) => {
1144
+ const dragSourceType = lodashEs.get(dragSource, "data._type", "");
1145
+ const dropTargetType = lodashEs.get(dropTarget2, "data._type", "");
1146
+ return canAcceptChildBlock(dropTargetType, dragSourceType);
1147
+ };
1148
+ if (void 0) {
1149
+ describe("canDropBlock Function", () => {
1150
+ it('should return false if dragSourceType is "Slot"', () => {
1151
+ const dragSource = { data: { _type: "Slot" } };
1152
+ const dropTarget2 = { data: {} };
1153
+ expect(canDropBlock({}, { dragSource, dropTarget: dropTarget2 })).toBe(true);
1154
+ });
1155
+ it("should return true if dropTargetType is empty", () => {
1156
+ const dragSource = { data: { _type: "Box" } };
1157
+ const dropTarget2 = { data: {} };
1158
+ expect(canDropBlock({}, { dragSource, dropTarget: dropTarget2 })).toBe(true);
1159
+ });
1160
+ });
1161
+ }
981
1162
  function duplicateBlocks(blocks, id, _parent) {
982
1163
  const children = lodashEs.filter(blocks, (c) => c._parent === id);
983
1164
  const newBlocks = [];
984
1165
  for (let i = 0; i < children.length; i++) {
1166
+ const slots = getSlots(children[i]);
1167
+ if (Object.keys(slots).length > 0) {
1168
+ Object.keys(slots).forEach((key) => {
1169
+ children[i][key] = `slot:${iconBase.generateUUID()}`;
1170
+ });
1171
+ }
985
1172
  if (lodashEs.filter(blocks, { _parent: children[i]._id }).length > 0) {
986
1173
  const newId = iconBase.generateUUID();
987
1174
  newBlocks.push({ ...children[i], oldId: children[i]._id, ...{ _id: newId, _parent } });
@@ -1046,21 +1233,15 @@ const getDuplicatedBlocks = (currentBlocks, id, newParentId = null) => {
1046
1233
  return lodashEs.omit(newBlock, ["global", "oldId"]);
1047
1234
  });
1048
1235
  };
1049
- const pageBlocksAtom = jotai.atom([]);
1050
- pageBlocksAtom.debugLabel = "pageBlocksAtom";
1051
- const convertToBlocksAtoms = (blocks) => {
1052
- return blocks.map((block) => ({
1053
- _type: block._type,
1054
- _id: block._id,
1055
- _parent: block._parent ?? null,
1056
- _atom: jotai.atom(block)
1057
- }));
1058
- };
1236
+ const presentBlocksAtom = jotai.atom([]);
1237
+ presentBlocksAtom.debugLabel = "presentBlocksAtom";
1059
1238
  const treeDSBlocks = jotai.atom((get) => {
1060
- const presentBlocks = get(pageBlocksAtom).map((block) => get(block._atom));
1061
- return convertToBlocksTree(presentBlocks);
1239
+ const presentBlocks = get(presentBlocksAtom);
1240
+ return convertToBlocksTree([...presentBlocks]);
1062
1241
  });
1063
1242
  treeDSBlocks.debugLabel = "treeDSBlocks";
1243
+ const pageBlocksAtomsAtom = splitAtom(presentBlocksAtom);
1244
+ pageBlocksAtomsAtom.debugLabel = "pageBlocksAtomsAtom";
1064
1245
  const builderActivePageAtom = jotai.atom("");
1065
1246
  builderActivePageAtom.debugLabel = "builderActivePageAtom";
1066
1247
  const destinationDropIndexAtom = jotai.atom(-1);
@@ -1072,87 +1253,10 @@ const globalBlocksAtom = jotai.atom((get) => {
1072
1253
  return lodashEs.filter(globalBlocks, (block) => lodashEs.has(block, "blockId"));
1073
1254
  });
1074
1255
  globalBlocksAtom.debugLabel = "globalBlocksAtom";
1075
- const canAcceptChildBlock = (parentType, childType) => {
1076
- if (!parentType) return true;
1077
- const blockDefinition = runtime.getRegisteredChaiBlock(parentType);
1078
- if (!blockDefinition) return false;
1079
- return lodashEs.has(blockDefinition, "canAcceptBlock") ? blockDefinition.canAcceptBlock(childType) : false;
1080
- };
1081
- const canAddChildBlock = (parentType) => {
1082
- const blockDefinition = runtime.getRegisteredChaiBlock(parentType);
1083
- if (!blockDefinition) return false;
1084
- return lodashEs.has(blockDefinition, "canAcceptBlock");
1085
- };
1086
- const canBeNestedInside = (parentType, childType) => {
1087
- const blockDefinition = runtime.getRegisteredChaiBlock(childType);
1088
- if (!blockDefinition) return true;
1089
- return lodashEs.has(blockDefinition, "canBeNested") ? blockDefinition.canBeNested(parentType) : true;
1090
- };
1091
- const canDuplicateBlock = (type) => {
1092
- const blockDefinition = runtime.getRegisteredChaiBlock(type);
1093
- if (!blockDefinition) return true;
1094
- return lodashEs.has(blockDefinition, "canDuplicate") ? blockDefinition.canDuplicate() : true;
1095
- };
1096
- const canDeleteBlock = (type) => {
1097
- const blockDefinition = runtime.getRegisteredChaiBlock(type);
1098
- if (!blockDefinition) return true;
1099
- return lodashEs.has(blockDefinition, "canDelete") ? blockDefinition.canDelete() : true;
1100
- };
1101
- const canDropBlock = (_currentTree, { dragSource, dropTarget: dropTarget2 }) => {
1102
- const dragSourceType = lodashEs.get(dragSource, "data._type", "");
1103
- const dropTargetType = lodashEs.get(dropTarget2, "data._type", "");
1104
- return canAcceptChildBlock(dropTargetType, dragSourceType);
1105
- };
1106
- if (void 0) {
1107
- describe("canDropBlock Function", () => {
1108
- it('should return false if dragSourceType is "Slot"', () => {
1109
- const dragSource = { data: { _type: "Slot" } };
1110
- const dropTarget2 = { data: {} };
1111
- expect(canDropBlock({}, { dragSource, dropTarget: dropTarget2 })).toBe(true);
1112
- });
1113
- it("should return true if dropTargetType is empty", () => {
1114
- const dragSource = { data: { _type: "Box" } };
1115
- const dropTarget2 = { data: {} };
1116
- expect(canDropBlock({}, { dragSource, dropTarget: dropTarget2 })).toBe(true);
1117
- });
1118
- });
1119
- }
1120
- const broadcastChannel = new BroadcastChannel("chaibuilder");
1121
- const useBroadcastChannel = () => {
1122
- const pageId = useBuilderProp("pageId", "chaibuilder_page");
1123
- const postMessage = web.useDebouncedCallback(
1124
- (message) => broadcastChannel.postMessage({ ...message, pageId }),
1125
- [pageId],
1126
- 200
1127
- );
1128
- return { postMessage };
1129
- };
1130
- const useUnmountBroadcastChannel = () => {
1131
- const [, setBlocks] = useBlocksStore();
1132
- const pageId = useBuilderProp("pageId", "chaibuilder_page");
1133
- const { updateBlocksProps } = useBlocksStoreManager();
1134
- React.useEffect(() => {
1135
- broadcastChannel.onmessageerror = (event) => {
1136
- console.log("error", event);
1137
- };
1138
- broadcastChannel.onmessage = (event) => {
1139
- if (event.data.type === "blocks-updated" && event.data.pageId === pageId) {
1140
- setBlocks(event.data.blocks);
1141
- }
1142
- if (event.data.type === "blocks-props-updated" && event.data.pageId === pageId) {
1143
- updateBlocksProps(event.data.blocks);
1144
- }
1145
- };
1146
- return () => {
1147
- broadcastChannel.onmessage = null;
1148
- broadcastChannel.onmessageerror = null;
1149
- };
1150
- }, [setBlocks, pageId]);
1151
- };
1152
1256
  const selectedBlockIdsAtom = jotai.atom([]);
1153
1257
  selectedBlockIdsAtom.debugLabel = "selectedBlockIdsAtom";
1154
1258
  const selectedBlocksAtom = jotai.atom((get) => {
1155
- const blocks = get(pageBlocksAtom);
1259
+ const blocks = get(presentBlocksAtom);
1156
1260
  const blockIds = get(selectedBlockIdsAtom);
1157
1261
  return lodashEs.map(
1158
1262
  lodashEs.filter(blocks, ({ _id }) => lodashEs.includes(blockIds, _id)),
@@ -1166,7 +1270,7 @@ const selectedBlockAtom = jotai.atom((get) => {
1166
1270
  return null;
1167
1271
  }
1168
1272
  if (blocks.length === 1) {
1169
- return get(lodashEs.first(blocks)._atom);
1273
+ return blocks[0];
1170
1274
  }
1171
1275
  });
1172
1276
  selectedBlockAtom.debugLabel = "selectedBlockAtom";
@@ -1174,7 +1278,7 @@ const getParentId = (block) => lodashEs.get(block, "_parent", null);
1174
1278
  const selectedBlocksParentsAtom = jotai.atom((get) => {
1175
1279
  const selectedBlocks = get(selectedBlocksAtom);
1176
1280
  const parentIds = lodashEs.map(selectedBlocks, getParentId);
1177
- return lodashEs.filter(get(pageBlocksAtom), (block) => lodashEs.includes(parentIds, block._id));
1281
+ return lodashEs.filter(get(presentBlocksAtom), (block) => lodashEs.includes(parentIds, block._id));
1178
1282
  });
1179
1283
  selectedBlocksParentsAtom.debugLabel = "selectedBlocksParentsAtom";
1180
1284
  const selectedBlockFlexChildAtom = jotai.atom(() => {
@@ -1196,7 +1300,7 @@ const useSelectedBlocksDisplayChild = () => ({
1196
1300
  const useSelectedBlock = () => jotai.useAtomValue(selectedBlockAtom);
1197
1301
  const selectedBlockHierarchy = jotai.atom((get) => {
1198
1302
  const selectedBlock = get(selectedBlockAtom);
1199
- const allBlocks = get(pageBlocksAtom);
1303
+ const allBlocks = get(presentBlocksAtom);
1200
1304
  let block = selectedBlock;
1201
1305
  const blocks = [selectedBlock];
1202
1306
  do {
@@ -1222,244 +1326,6 @@ const useSelectedBlockIds = () => {
1222
1326
  );
1223
1327
  return [blockIds, setBlockIds, toggleSelectedBlockId];
1224
1328
  };
1225
- const removeNestedBlocks = (blocks, blockIds) => {
1226
- const _blockIds = [];
1227
- const _blocks = lodashEs.filter(blocks, (block) => {
1228
- if (lodashEs.includes(blockIds, block._id) || lodashEs.includes(blockIds, block._parent)) {
1229
- _blockIds.push(block._id);
1230
- return false;
1231
- }
1232
- return true;
1233
- });
1234
- if (!lodashEs.isEmpty(_blockIds)) return removeNestedBlocks(_blocks, _blockIds);
1235
- return _blocks;
1236
- };
1237
- const useRemoveBlocks = () => {
1238
- const [presentBlocks] = useBlocksStore();
1239
- const [ids2, setSelectedIds] = useSelectedBlockIds();
1240
- const { setNewBlocks } = useBlocksStoreUndoableActions();
1241
- return React.useCallback(
1242
- (blockIds) => {
1243
- var _a;
1244
- const parentBlockId = ((_a = lodashEs.find(presentBlocks, { _id: blockIds[0] })) == null ? void 0 : _a._parent) || null;
1245
- setNewBlocks(removeNestedBlocks(presentBlocks, blockIds));
1246
- setTimeout(() => setSelectedIds(parentBlockId ? [parentBlockId] : []), 200);
1247
- },
1248
- [presentBlocks, setSelectedIds, ids2]
1249
- );
1250
- };
1251
- const writeAtomValue = jotai.atom(
1252
- null,
1253
- // it's a convention to pass `null` for the first argument
1254
- (get, set, { id, props }) => {
1255
- const blockAsAtoms = get(pageBlocksAtom);
1256
- console.log("From Atom callback", blockAsAtoms);
1257
- const blockAtom = lodashEs.find(blockAsAtoms, (b) => b._id === id);
1258
- if (!blockAtom) {
1259
- throw new Error(`Block with id ${id} not found`);
1260
- }
1261
- return set(blockAtom._atom, { ...get(blockAtom._atom), ...props });
1262
- }
1263
- );
1264
- const useUpdateBlockAtom = () => {
1265
- return jotai.useSetAtom(writeAtomValue);
1266
- };
1267
- const useGetBlockAtomValue = () => {
1268
- return useAtomCallback(
1269
- React.useCallback((get, _set, id) => {
1270
- const blockAsAtoms = get(pageBlocksAtom);
1271
- console.log("Block As Atoms", blockAsAtoms);
1272
- const blockAtom = lodashEs.find(blockAsAtoms, (b) => b._id === id);
1273
- if (!blockAtom) {
1274
- throw new Error(`Block with id ${id} not found`);
1275
- }
1276
- return get(blockAtom._atom);
1277
- }, [])
1278
- );
1279
- };
1280
- function insertBlocksAtPosition(allBlocks, newBlocks, parentId, position) {
1281
- let parentBlocks = allBlocks.filter((block) => !block._parent);
1282
- if (parentId) {
1283
- parentBlocks = allBlocks.filter((block) => block._parent === parentId);
1284
- }
1285
- const insertPosition = !isNaN(position) || position > -1 ? Math.min(position, parentBlocks.length) : parentBlocks.length;
1286
- let insertIndex = allBlocks.length;
1287
- for (let i = 0, count = 0; i < allBlocks.length; i++) {
1288
- if (allBlocks[i]._parent === parentId) {
1289
- if (count === insertPosition) {
1290
- insertIndex = i;
1291
- break;
1292
- }
1293
- count++;
1294
- }
1295
- }
1296
- if (!parentId && position !== void 0 && position >= parentBlocks.length) {
1297
- insertIndex = allBlocks.length;
1298
- }
1299
- return [...allBlocks.slice(0, insertIndex), ...newBlocks, ...allBlocks.slice(insertIndex)];
1300
- }
1301
- function getBlocksTree(blocks) {
1302
- return convertToBlocksTree(blocks);
1303
- }
1304
- const nestedToFlatArray = (nestedJson, parent) => lodashEs.flatten(
1305
- nestedJson.map((block) => {
1306
- block = parent ? { ...block, _parent: parent } : { ...block };
1307
- if (block.children) {
1308
- const children = [...block.children];
1309
- delete block.children;
1310
- return lodashEs.flatten([block, ...nestedToFlatArray(children, block._id)]);
1311
- }
1312
- return block;
1313
- })
1314
- );
1315
- function setProjectBlocksInMemory(nodes, initial = false) {
1316
- for (let i = 0; i < nodes.length; i++) {
1317
- const element = nodes[i];
1318
- if (element.global && !initial) {
1319
- nodes[i] = {
1320
- type: "GlobalBlock",
1321
- blockId: element.blockId,
1322
- _parent: lodashEs.get(element, "_parent", null),
1323
- _id: element._id
1324
- };
1325
- } else if (element.children && element.children.length) {
1326
- setProjectBlocksInMemory(element.children);
1327
- }
1328
- }
1329
- }
1330
- function getInnerBlocks(flatArr) {
1331
- let blocks = [];
1332
- let pBlocks = lodashEs.filter(flatArr, { type: "GlobalBlock" });
1333
- if (pBlocks.length > 0) {
1334
- pBlocks = lodashEs.map(pBlocks, getPBlocks);
1335
- lodashEs.each(pBlocks, (pBlock) => {
1336
- blocks = [...blocks, ...getSingleBlock(pBlock)];
1337
- });
1338
- }
1339
- return blocks;
1340
- }
1341
- function getSingleBlock(flatArray) {
1342
- let blocks = [];
1343
- const parent = lodashEs.get(lodashEs.first(flatArray), "_parent", null);
1344
- lodashEs.set(lodashEs.first(flatArray), "_parent", null);
1345
- const block = [flatToNestedInstance.convert(clone(flatArray))];
1346
- setProjectBlocksInMemory(block, true);
1347
- let flat = nestedToFlatArray(block, flatArray[0]._id);
1348
- flat = lodashEs.set(flat, "0._parent", parent);
1349
- blocks = [...blocks, flat, ...getInnerBlocks(flat)];
1350
- return blocks;
1351
- }
1352
- function getPBlocks(block) {
1353
- const rootBlock = lodashEs.find(FLAT_ARRAY, { _id: block._id });
1354
- if (!rootBlock) return [];
1355
- const blocks = [rootBlock];
1356
- const children = lodashEs.filter(FLAT_ARRAY, { _parent: block._id });
1357
- if (children.length) {
1358
- return lodashEs.flatten([...blocks, ...lodashEs.flatten(lodashEs.map(children, getPBlocks))]);
1359
- }
1360
- return lodashEs.flatten(blocks);
1361
- }
1362
- const clone = (obj) => JSON.parse(JSON.stringify(obj));
1363
- let FLAT_ARRAY = [];
1364
- function splitPageBlocks(allPageBlocks) {
1365
- FLAT_ARRAY = allPageBlocks;
1366
- const clonedTree = getBlocksTree(clone(allPageBlocks));
1367
- setProjectBlocksInMemory(clonedTree);
1368
- const pageBlocks = nestedToFlatArray(clonedTree, null);
1369
- const globalBlocks = getInnerBlocks(pageBlocks);
1370
- const mappedBlocks = {};
1371
- lodashEs.each(globalBlocks, (projectBlock) => lodashEs.set(mappedBlocks, lodashEs.first(projectBlock).blockId, projectBlock));
1372
- return [pageBlocks, mappedBlocks];
1373
- }
1374
- function flattenTree(node) {
1375
- let flatArray = [];
1376
- node.walk((n) => {
1377
- delete n.model.children;
1378
- flatArray.push(n.model);
1379
- return true;
1380
- });
1381
- return flatArray;
1382
- }
1383
- function findNodeById(node, id) {
1384
- return node.first((n) => n.model._id === id) || null;
1385
- }
1386
- function moveNode(rootNode, nodeIdToMove, newParentId, position) {
1387
- const nodeToMove = findNodeById(rootNode, nodeIdToMove);
1388
- const newParentNode = findNodeById(rootNode, newParentId);
1389
- if (nodeToMove && newParentNode) {
1390
- nodeToMove.drop();
1391
- if (!newParentNode.children) {
1392
- newParentNode.model.children = [];
1393
- }
1394
- try {
1395
- newParentNode.addChildAtIndex(nodeToMove, position);
1396
- } catch (error) {
1397
- console.error("Error adding child to parent:", error);
1398
- return false;
1399
- }
1400
- return true;
1401
- }
1402
- return false;
1403
- }
1404
- function moveBlocksWithChildren(_blocks, idToMove, newParentId, newPosition, updateBlockAtom) {
1405
- if (!idToMove) return _blocks;
1406
- newParentId = newParentId || "root";
1407
- const tree2 = new TreeModel();
1408
- const root = tree2.parse({ _id: "root", children: getBlocksTree(_blocks) });
1409
- if (moveNode(root, idToMove, newParentId, newPosition)) {
1410
- const newBlocks = flattenTree(root);
1411
- const movedBlock = newBlocks.find((block) => block._id === idToMove);
1412
- if (movedBlock) {
1413
- movedBlock._parent = newParentId === "root" ? null : newParentId;
1414
- updateBlockAtom({ id: movedBlock._id, props: { _parent: movedBlock._parent } });
1415
- }
1416
- newBlocks.shift();
1417
- return convertToBlocksAtoms(newBlocks);
1418
- }
1419
- return _blocks;
1420
- }
1421
- const useBlocksStoreManager = () => {
1422
- const [, setBlocks] = useBlocksStore();
1423
- const { postMessage } = useBroadcastChannel();
1424
- const updateBlockAtom = useUpdateBlockAtom();
1425
- return {
1426
- setNewBlocks: (newBlocks) => {
1427
- setBlocks(newBlocks);
1428
- postMessage({ type: "blocks-updated", blocks: newBlocks });
1429
- },
1430
- addBlocks: (newBlocks, parent, position) => {
1431
- setBlocks((prevBlocks) => {
1432
- const blocks = insertBlocksAtPosition(prevBlocks, newBlocks, parent, position);
1433
- postMessage({ type: "blocks-updated", blocks });
1434
- return blocks;
1435
- });
1436
- },
1437
- removeBlocks: (blockIds) => {
1438
- setBlocks((prevBlocks) => {
1439
- const blocks = removeNestedBlocks(prevBlocks, blockIds);
1440
- postMessage({ type: "blocks-updated", blocks });
1441
- return blocks;
1442
- });
1443
- },
1444
- moveBlocks: (blockIds, newParent, position) => {
1445
- setBlocks((prevBlocks) => {
1446
- let blocks = prevBlocks;
1447
- for (let i = 0; i < blockIds.length; i++) {
1448
- blocks = moveBlocksWithChildren(blocks, blockIds[i], newParent, position, updateBlockAtom);
1449
- }
1450
- postMessage({ type: "blocks-updated", blocks });
1451
- return blocks;
1452
- });
1453
- },
1454
- updateBlocksProps: (blocks) => {
1455
- blocks.forEach((block) => {
1456
- const updatedBlock = lodashEs.omit(block, "_id");
1457
- updateBlockAtom({ id: block._id, props: updatedBlock });
1458
- });
1459
- postMessage({ type: "blocks-props-updated", blocks });
1460
- }
1461
- };
1462
- };
1463
1329
  var undomanager = { exports: {} };
1464
1330
  var hasRequiredUndomanager;
1465
1331
  function requireUndomanager() {
@@ -1613,8 +1479,81 @@ function requireUndomanager() {
1613
1479
  })(undomanager);
1614
1480
  return undomanager.exports;
1615
1481
  }
1616
- var undomanagerExports = requireUndomanager();
1617
- const UndoManager = /* @__PURE__ */ ChaiThemeFn.getDefaultExportFromCjs(undomanagerExports);
1482
+ var undomanagerExports = requireUndomanager();
1483
+ const UndoManager = /* @__PURE__ */ ChaiThemeFn.getDefaultExportFromCjs(undomanagerExports);
1484
+ function getBlocksTree(blocks) {
1485
+ return convertToBlocksTree(blocks);
1486
+ }
1487
+ const nestedToFlatArray = (nestedJson, parent) => lodashEs.flatten(
1488
+ nestedJson.map((block) => {
1489
+ block = parent ? { ...block, _parent: parent } : { ...block };
1490
+ if (block.children) {
1491
+ const children = [...block.children];
1492
+ delete block.children;
1493
+ return lodashEs.flatten([block, ...nestedToFlatArray(children, block._id)]);
1494
+ }
1495
+ return block;
1496
+ })
1497
+ );
1498
+ function setProjectBlocksInMemory(nodes, initial = false) {
1499
+ for (let i = 0; i < nodes.length; i++) {
1500
+ const element = nodes[i];
1501
+ if (element.global && !initial) {
1502
+ nodes[i] = {
1503
+ type: "GlobalBlock",
1504
+ blockId: element.blockId,
1505
+ _parent: lodashEs.get(element, "_parent", null),
1506
+ _id: element._id
1507
+ };
1508
+ } else if (element.children && element.children.length) {
1509
+ setProjectBlocksInMemory(element.children);
1510
+ }
1511
+ }
1512
+ }
1513
+ function getInnerBlocks(flatArr) {
1514
+ let blocks = [];
1515
+ let pBlocks = lodashEs.filter(flatArr, { type: "GlobalBlock" });
1516
+ if (pBlocks.length > 0) {
1517
+ pBlocks = lodashEs.map(pBlocks, getPBlocks);
1518
+ lodashEs.each(pBlocks, (pBlock) => {
1519
+ blocks = [...blocks, ...getSingleBlock(pBlock)];
1520
+ });
1521
+ }
1522
+ return blocks;
1523
+ }
1524
+ function getSingleBlock(flatArray) {
1525
+ let blocks = [];
1526
+ const parent = lodashEs.get(lodashEs.first(flatArray), "_parent", null);
1527
+ lodashEs.set(lodashEs.first(flatArray), "_parent", null);
1528
+ const block = [flatToNestedInstance.convert(clone(flatArray))];
1529
+ setProjectBlocksInMemory(block, true);
1530
+ let flat = nestedToFlatArray(block, flatArray[0]._id);
1531
+ flat = lodashEs.set(flat, "0._parent", parent);
1532
+ blocks = [...blocks, flat, ...getInnerBlocks(flat)];
1533
+ return blocks;
1534
+ }
1535
+ function getPBlocks(block) {
1536
+ const rootBlock = lodashEs.find(FLAT_ARRAY, { _id: block._id });
1537
+ if (!rootBlock) return [];
1538
+ const blocks = [rootBlock];
1539
+ const children = lodashEs.filter(FLAT_ARRAY, { _parent: block._id });
1540
+ if (children.length) {
1541
+ return lodashEs.flatten([...blocks, ...lodashEs.flatten(lodashEs.map(children, getPBlocks))]);
1542
+ }
1543
+ return lodashEs.flatten(blocks);
1544
+ }
1545
+ const clone = (obj) => JSON.parse(JSON.stringify(obj));
1546
+ let FLAT_ARRAY = [];
1547
+ function splitPageBlocks(allPageBlocks) {
1548
+ FLAT_ARRAY = allPageBlocks;
1549
+ const clonedTree = getBlocksTree(clone(allPageBlocks));
1550
+ setProjectBlocksInMemory(clonedTree);
1551
+ const pageBlocks = nestedToFlatArray(clonedTree, null);
1552
+ const globalBlocks = getInnerBlocks(pageBlocks);
1553
+ const mappedBlocks = {};
1554
+ lodashEs.each(globalBlocks, (projectBlock) => lodashEs.set(mappedBlocks, lodashEs.first(projectBlock).blockId, projectBlock));
1555
+ return [pageBlocks, mappedBlocks];
1556
+ }
1618
1557
  const MODIFIERS = [
1619
1558
  "hover",
1620
1559
  "focus",
@@ -1695,10 +1634,9 @@ const useGetPageData = () => {
1695
1634
  const [projectOptions] = useBrandingOptions();
1696
1635
  const { currentPage } = useCurrentPage();
1697
1636
  const [presentBlocks] = useBlocksStore();
1698
- const getBlockAtomValue = useGetBlockAtomValue();
1699
1637
  return React.useCallback(() => {
1700
1638
  const blocks = lodashEs.map(presentBlocks, (block) => {
1701
- return lodashEs.omit(getBlockAtomValue(block._id), getBlockBuilderProps(block._type));
1639
+ return lodashEs.omit(block, getBlockBuilderProps(block._type));
1702
1640
  });
1703
1641
  const [pageFilteredBlocks = []] = splitPageBlocks(blocks);
1704
1642
  return {
@@ -1826,8 +1764,232 @@ const useUndoManager = () => {
1826
1764
  clear: undoManager.clear
1827
1765
  };
1828
1766
  };
1767
+ const broadcastChannel = new BroadcastChannel("chaibuilder");
1768
+ const useBroadcastChannel = () => {
1769
+ const pageId = useBuilderProp("pageId", "chaibuilder_page");
1770
+ const postMessage = web.useDebouncedCallback(
1771
+ (message) => broadcastChannel.postMessage({ ...message, pageId }),
1772
+ [pageId],
1773
+ 200
1774
+ );
1775
+ return { postMessage };
1776
+ };
1777
+ const useUnmountBroadcastChannel = () => {
1778
+ const [, setBlocks] = useBlocksStore();
1779
+ const pageId = useBuilderProp("pageId", "chaibuilder_page");
1780
+ const { updateBlocksProps } = useBlocksStoreManager();
1781
+ React.useEffect(() => {
1782
+ broadcastChannel.onmessageerror = (event) => {
1783
+ console.log("error", event);
1784
+ };
1785
+ broadcastChannel.onmessage = (event) => {
1786
+ if (event.data.type === "blocks-updated" && event.data.pageId === pageId) {
1787
+ setBlocks(event.data.blocks);
1788
+ }
1789
+ if (event.data.type === "blocks-props-updated" && event.data.pageId === pageId) {
1790
+ updateBlocksProps(event.data.blocks);
1791
+ }
1792
+ };
1793
+ return () => {
1794
+ broadcastChannel.onmessage = null;
1795
+ broadcastChannel.onmessageerror = null;
1796
+ };
1797
+ }, [setBlocks, pageId]);
1798
+ };
1799
+ const removeNestedBlocks = (blocks, blockIds) => {
1800
+ const _blockIds = [];
1801
+ const _blocks = lodashEs.filter(blocks, (block) => {
1802
+ if (lodashEs.includes(blockIds, block._id) || lodashEs.includes(blockIds, block._parent)) {
1803
+ _blockIds.push(block._id);
1804
+ return false;
1805
+ }
1806
+ return true;
1807
+ });
1808
+ if (!lodashEs.isEmpty(_blockIds)) return removeNestedBlocks(_blocks, _blockIds);
1809
+ return _blocks;
1810
+ };
1811
+ const useRemoveBlocks = () => {
1812
+ const [presentBlocks] = useBlocksStore();
1813
+ const [ids2, setSelectedIds] = useSelectedBlockIds();
1814
+ const { setNewBlocks } = useBlocksStoreUndoableActions();
1815
+ return React.useCallback(
1816
+ (blockIds) => {
1817
+ var _a;
1818
+ const parentBlockId = ((_a = lodashEs.find(presentBlocks, { _id: blockIds[0] })) == null ? void 0 : _a._parent) || null;
1819
+ setNewBlocks(removeNestedBlocks(presentBlocks, blockIds));
1820
+ setTimeout(() => setSelectedIds(parentBlockId ? [parentBlockId] : []), 200);
1821
+ },
1822
+ [presentBlocks, setSelectedIds, ids2]
1823
+ );
1824
+ };
1825
+ const writeAtomValue = jotai.atom(
1826
+ null,
1827
+ // it's a convention to pass `null` for the first argument
1828
+ (get, set, { id, props }) => {
1829
+ const blockAsAtoms = get(pageBlocksAtomsAtom);
1830
+ const blockAtom = lodashEs.find(blockAsAtoms, (b) => get(b)._id === id);
1831
+ if (!blockAtom) {
1832
+ throw new Error(`Block with id ${id} not found`);
1833
+ }
1834
+ return set(blockAtom, { ...get(blockAtom), ...props });
1835
+ }
1836
+ );
1837
+ const useUpdateBlockAtom = () => {
1838
+ return jotai.useSetAtom(writeAtomValue);
1839
+ };
1840
+ const useGetBlockAtomValue = (splitAtoms) => {
1841
+ return useAtomCallback(
1842
+ React.useCallback(
1843
+ (get, _set, idOrAtom) => {
1844
+ const blockAsAtoms = get(pageBlocksAtomsAtom);
1845
+ const blockAtom = lodashEs.find(
1846
+ blockAsAtoms,
1847
+ (b) => get(b)._id === (lodashEs.isString(idOrAtom) ? idOrAtom : get(idOrAtom)._id)
1848
+ );
1849
+ if (!blockAtom) {
1850
+ console.warn(`Block with id ${idOrAtom} not found`);
1851
+ return;
1852
+ }
1853
+ return get(blockAtom);
1854
+ },
1855
+ [splitAtoms]
1856
+ )
1857
+ );
1858
+ };
1859
+ const useGetBlockAtom = (splitAtoms) => {
1860
+ return useAtomCallback(
1861
+ React.useCallback(
1862
+ (get, _set, idOrAtom) => {
1863
+ const blockAsAtoms = get(splitAtoms ?? pageBlocksAtomsAtom);
1864
+ const blockAtom = lodashEs.find(
1865
+ blockAsAtoms,
1866
+ (b) => get(b)._id === (lodashEs.isString(idOrAtom) ? idOrAtom : get(idOrAtom)._id)
1867
+ );
1868
+ if (!blockAtom) {
1869
+ console.warn(`Block with id ${idOrAtom} not found`);
1870
+ return;
1871
+ }
1872
+ return blockAtom;
1873
+ },
1874
+ [splitAtoms]
1875
+ )
1876
+ );
1877
+ };
1878
+ function insertBlocksAtPosition(allBlocks, newBlocks, parentId, position) {
1879
+ let parentBlocks = allBlocks.filter((block) => !block._parent);
1880
+ if (parentId) {
1881
+ parentBlocks = allBlocks.filter((block) => block._parent === parentId);
1882
+ }
1883
+ const insertPosition = !isNaN(position) || position > -1 ? Math.min(position, parentBlocks.length) : parentBlocks.length;
1884
+ let insertIndex = allBlocks.length;
1885
+ for (let i = 0, count = 0; i < allBlocks.length; i++) {
1886
+ if (allBlocks[i]._parent === parentId) {
1887
+ if (count === insertPosition) {
1888
+ insertIndex = i;
1889
+ break;
1890
+ }
1891
+ count++;
1892
+ }
1893
+ }
1894
+ if (!parentId && position !== void 0 && position >= parentBlocks.length) {
1895
+ insertIndex = allBlocks.length;
1896
+ }
1897
+ return [...allBlocks.slice(0, insertIndex), ...newBlocks, ...allBlocks.slice(insertIndex)];
1898
+ }
1899
+ function flattenTree(node) {
1900
+ let flatArray = [];
1901
+ node.walk((n) => {
1902
+ delete n.model.children;
1903
+ flatArray.push(n.model);
1904
+ return true;
1905
+ });
1906
+ return flatArray;
1907
+ }
1908
+ function findNodeById(node, id) {
1909
+ return node.first((n) => n.model._id === id) || null;
1910
+ }
1911
+ function moveNode(rootNode, nodeIdToMove, newParentId, position) {
1912
+ const nodeToMove = findNodeById(rootNode, nodeIdToMove);
1913
+ const newParentNode = findNodeById(rootNode, newParentId);
1914
+ if (nodeToMove && newParentNode) {
1915
+ nodeToMove.drop();
1916
+ if (!newParentNode.children) {
1917
+ newParentNode.model.children = [];
1918
+ }
1919
+ try {
1920
+ newParentNode.addChildAtIndex(nodeToMove, position);
1921
+ } catch (error) {
1922
+ console.error("Error adding child to parent:", error);
1923
+ return false;
1924
+ }
1925
+ return true;
1926
+ }
1927
+ return false;
1928
+ }
1929
+ function moveBlocksWithChildren(_blocks, idToMove, newParentId, newPosition) {
1930
+ if (!idToMove) return _blocks;
1931
+ newParentId = newParentId || "root";
1932
+ const tree2 = new TreeModel();
1933
+ const root = tree2.parse({ _id: "root", children: getBlocksTree(_blocks) });
1934
+ if (moveNode(root, idToMove, newParentId, newPosition)) {
1935
+ const newBlocks = flattenTree(root);
1936
+ const movedBlock = newBlocks.find((block) => block._id === idToMove);
1937
+ if (movedBlock) movedBlock._parent = newParentId === "root" ? null : newParentId;
1938
+ newBlocks.shift();
1939
+ return newBlocks;
1940
+ }
1941
+ return _blocks;
1942
+ }
1943
+ const useBlocksStoreManager = () => {
1944
+ const [, setBlocks] = useBlocksStore();
1945
+ const { postMessage } = useBroadcastChannel();
1946
+ const updateBlockAtom = useUpdateBlockAtom();
1947
+ return {
1948
+ setNewBlocks: (newBlocks) => {
1949
+ setBlocks(newBlocks);
1950
+ postMessage({ type: "blocks-updated", blocks: newBlocks });
1951
+ },
1952
+ addBlocks: (newBlocks, parent, position) => {
1953
+ setBlocks((prevBlocks) => {
1954
+ const blocks = insertBlocksAtPosition(prevBlocks, newBlocks, parent, position);
1955
+ postMessage({ type: "blocks-updated", blocks });
1956
+ return blocks;
1957
+ });
1958
+ },
1959
+ removeBlocks: (blockIds) => {
1960
+ setBlocks((prevBlocks) => {
1961
+ const blocks = removeNestedBlocks(prevBlocks, blockIds);
1962
+ postMessage({ type: "blocks-updated", blocks });
1963
+ return blocks;
1964
+ });
1965
+ },
1966
+ moveBlocks: (blockIds, newParent, position) => {
1967
+ setBlocks((prevBlocks) => {
1968
+ let blocks = [...prevBlocks];
1969
+ for (let i = 0; i < blockIds.length; i++) {
1970
+ blocks = moveBlocksWithChildren(blocks, blockIds[i], newParent, position);
1971
+ }
1972
+ lodashEs.each(blockIds, (id) => {
1973
+ const block = lodashEs.find(blocks, (b) => b._id === id);
1974
+ if (block) {
1975
+ updateBlockAtom({ id, props: { _parent: block._parent || null } });
1976
+ }
1977
+ });
1978
+ postMessage({ type: "blocks-updated", blocks });
1979
+ return blocks;
1980
+ });
1981
+ },
1982
+ updateBlocksProps: (blocks) => {
1983
+ blocks.forEach((block) => {
1984
+ const updatedBlock = lodashEs.omit(block, "_id");
1985
+ updateBlockAtom({ id: block._id, props: updatedBlock });
1986
+ });
1987
+ postMessage({ type: "blocks-props-updated", blocks });
1988
+ }
1989
+ };
1990
+ };
1829
1991
  const useBlocksStore = () => {
1830
- return jotai.useAtom(pageBlocksAtom);
1992
+ return jotai.useAtom(presentBlocksAtom);
1831
1993
  };
1832
1994
  const useBlocksStoreUndoableActions = () => {
1833
1995
  const { add } = useUndoManager();
@@ -1961,7 +2123,7 @@ const useAddBlock = () => {
1961
2123
  blocks[0]._parent = parentBlock._parent;
1962
2124
  parentBlockId = parentBlock._parent;
1963
2125
  }
1964
- addBlocks(convertToBlocksAtoms(blocks), parentBlockId, position);
2126
+ addBlocks(blocks, parentBlockId, position);
1965
2127
  setSelected([(_a = lodashEs.first(blocks)) == null ? void 0 : _a._id]);
1966
2128
  return lodashEs.first(blocks);
1967
2129
  },
@@ -1993,7 +2155,7 @@ const useAddBlock = () => {
1993
2155
  parentBlockId = parentBlock._parent;
1994
2156
  }
1995
2157
  const newBlocks = [newBlock];
1996
- addBlocks(convertToBlocksAtoms(newBlocks), parentBlockId, position);
2158
+ addBlocks(newBlocks, parentBlockId, position);
1997
2159
  setSelected([newBlock._id]);
1998
2160
  return newBlock;
1999
2161
  },
@@ -3191,9 +3353,12 @@ const selectedStylingBlocksAtom = jotai.atom([]);
3191
3353
  selectedStylingBlocksAtom.debugLabel = "selectedStylingBlocksAtom";
3192
3354
  const useSelectedStylingBlocks = () => jotai.useAtom(selectedStylingBlocksAtom);
3193
3355
  const addClassesToBlocksAtom = jotai.atom(null, (get, _set, { blockIds, newClasses }) => {
3194
- const blockAtoms = lodashEs.map(
3195
- lodashEs.filter(get(pageBlocksAtom), (block) => blockIds.includes(block._id)),
3196
- (block) => block._atom
3356
+ const blockAtoms = lodashEs.filter(
3357
+ get(pageBlocksAtomsAtom),
3358
+ (blockAtom) => (
3359
+ // @ts-ignore
3360
+ blockIds.includes(get(blockAtom)._id)
3361
+ )
3197
3362
  );
3198
3363
  const styleBlock = lodashEs.first(get(selectedStylingBlocksAtom));
3199
3364
  return lodashEs.map(blockAtoms, (blockAtom) => {
@@ -3307,7 +3472,7 @@ const useDuplicateBlocks = () => {
3307
3472
  const blockPosition = siblingBlocks.indexOf(block);
3308
3473
  const newBlockPosition = blockPosition + 1;
3309
3474
  const newBlocks = getDuplicatedBlocks(presentBlocks, blockId, parentId);
3310
- addBlocks(convertToBlocksAtoms(newBlocks), parentId, newBlockPosition);
3475
+ addBlocks(newBlocks, parentId, newBlockPosition);
3311
3476
  newBlockIds.push(lodashEs.get(newBlocks, "0._id", ""));
3312
3477
  });
3313
3478
  setSelected(newBlockIds);
@@ -3341,7 +3506,7 @@ const useCanPaste = () => {
3341
3506
  };
3342
3507
  };
3343
3508
  const useMoveCutBlocks = () => {
3344
- const presentBlocks = jotai.useAtomValue(pageBlocksAtom);
3509
+ const presentBlocks = jotai.useAtomValue(presentBlocksAtom);
3345
3510
  const { moveBlocks: moveBlocks2 } = useBlocksStoreUndoableActions();
3346
3511
  return React.useCallback(
3347
3512
  (blockIds, newParentId) => {
@@ -3419,9 +3584,12 @@ const usePreviewMode = () => {
3419
3584
  };
3420
3585
  const removeClassFromBlocksAtom = jotai.atom(null, (get, _set, { blockIds, fullClasses }) => {
3421
3586
  const styleBlock = lodashEs.first(get(selectedStylingBlocksAtom));
3422
- const blockAtoms = lodashEs.map(
3423
- lodashEs.filter(get(pageBlocksAtom), (block) => blockIds.includes(block._id)),
3424
- (block) => block._atom
3587
+ const blockAtoms = lodashEs.filter(
3588
+ get(pageBlocksAtomsAtom),
3589
+ (blockAtom) => (
3590
+ // @ts-ignore
3591
+ blockIds.includes(get(blockAtom)._id)
3592
+ )
3425
3593
  );
3426
3594
  return lodashEs.map(blockAtoms, (blockAtom) => {
3427
3595
  const block = get(blockAtom);
@@ -3624,23 +3792,27 @@ const useBlockHighlight = () => {
3624
3792
  var _a;
3625
3793
  return (iframe == null ? void 0 : iframe.contentDocument) || ((_a = iframe == null ? void 0 : iframe.contentWindow) == null ? void 0 : _a.document);
3626
3794
  }, [iframe]);
3627
- const highlightBlock = (elementOrID) => {
3628
- if (lastHighlighted) {
3629
- lastHighlighted.removeAttribute("data-highlighted");
3630
- }
3631
- if (typeof elementOrID !== "string") {
3632
- elementOrID.setAttribute("data-highlighted", "true");
3633
- lastHighlighted = elementOrID;
3634
- } else if (typeof elementOrID === "string") {
3635
- const element = innerDoc.querySelector(`[data-block-id="${elementOrID}"]`);
3636
- if (element) {
3637
- element.setAttribute("data-highlighted", "true");
3638
- lastHighlighted = element;
3795
+ const highlightBlock = React.useCallback(
3796
+ (elementOrID) => {
3797
+ if (!innerDoc) return;
3798
+ if (lastHighlighted) {
3799
+ lastHighlighted.removeAttribute("data-highlighted");
3800
+ }
3801
+ if (typeof elementOrID !== "string") {
3802
+ elementOrID.setAttribute("data-highlighted", "true");
3803
+ lastHighlighted = elementOrID;
3804
+ } else if (typeof elementOrID === "string") {
3805
+ const element = innerDoc.querySelector(`[data-block-id="${elementOrID}"]`);
3806
+ if (element) {
3807
+ element.setAttribute("data-highlighted", "true");
3808
+ lastHighlighted = element;
3809
+ }
3810
+ } else {
3811
+ lastHighlighted = null;
3639
3812
  }
3640
- } else {
3641
- lastHighlighted = null;
3642
- }
3643
- };
3813
+ },
3814
+ [innerDoc]
3815
+ );
3644
3816
  const clearHighlight = () => {
3645
3817
  if (lastHighlighted) {
3646
3818
  lastHighlighted.removeAttribute("data-highlighted");
@@ -3653,7 +3825,7 @@ const globalBlocksStoreAtom = atom({});
3653
3825
  const globalBlocksLoadingStateAtom = atom({});
3654
3826
  const useGlobalBlocksStore = () => {
3655
3827
  const [globalBlocks, setGlobalBlocks] = useAtom(globalBlocksStoreAtom);
3656
- const getGlobalBlocks = React.useCallback((globalBlockId) => lodashEs.get(globalBlocks, globalBlockId, []), [globalBlocks]);
3828
+ const getGlobalBlocks = React.useCallback((globalBlock) => lodashEs.get(globalBlocks, globalBlock, []), [globalBlocks]);
3657
3829
  const reset = React.useCallback(() => setGlobalBlocks({}), [setGlobalBlocks]);
3658
3830
  return { getGlobalBlocks, reset };
3659
3831
  };
@@ -3661,14 +3833,10 @@ const useWatchGlobalBlocks = () => {
3661
3833
  const [blocksStore] = useBlocksStore();
3662
3834
  const [globalBlocks, setGlobalBlocks] = useAtom(globalBlocksStoreAtom);
3663
3835
  const [globalBlocksLoadingState, setGlobalBlocksLoadingState] = useAtom(globalBlocksLoadingStateAtom);
3664
- const getBlockAtomValue = useGetBlockAtomValue();
3665
3836
  const getGlobalBlockBlocks = useBuilderProp("getGlobalBlockBlocks", async (_key) => []);
3666
3837
  const globalBlocksList = React.useMemo(() => {
3667
3838
  const globalBlocks2 = blocksStore.filter((block) => block._type === "GlobalBlock");
3668
- return globalBlocks2.filter((block) => block._type === "GlobalBlock").map((block) => {
3669
- const blockValue = getBlockAtomValue(block._id);
3670
- return blockValue.globalBlock;
3671
- });
3839
+ return globalBlocks2.filter((block) => block._type === "GlobalBlock").map((block) => block.globalBlock);
3672
3840
  }, [blocksStore]);
3673
3841
  React.useEffect(() => {
3674
3842
  lodashEs.forEach(globalBlocksList, (globalBlock) => {
@@ -4070,7 +4238,7 @@ const useAiAssistant = () => {
4070
4238
  };
4071
4239
  const wrapperBlockAtom = jotai.atom((get) => {
4072
4240
  var _a;
4073
- const blocks = get(pageBlocksAtom);
4241
+ const blocks = get(presentBlocksAtom);
4074
4242
  const blockIds = get(selectedBlockIdsAtom);
4075
4243
  const blockId = blockIds.length === 1 ? blockIds[0] : null;
4076
4244
  if (!blockId) return null;
@@ -4928,23 +5096,28 @@ const BlockRenderer = ({ blockAtom, children }) => {
4928
5096
  const GlobalBlocksRenderer = ({ blockAtom }) => {
4929
5097
  const { getGlobalBlocks } = useGlobalBlocksStore();
4930
5098
  const [block] = jotai.useAtom(blockAtom);
4931
- const globalBlocks = React.useMemo(() => getGlobalBlocks(block == null ? void 0 : block.globalBlock), [block == null ? void 0 : block.globalBlock, getGlobalBlocks]);
4932
- const globalBlocksAtoms = React.useMemo(() => convertToBlocksAtoms(globalBlocks), [globalBlocks]);
4933
- return /* @__PURE__ */ jsxRuntime.jsx(BlocksRenderer, { blocks: globalBlocksAtoms, filterFn: (block2) => lodashEs.isEmpty(block2._parent) });
5099
+ const globalBlocks = React.useMemo(() => getGlobalBlocks((block == null ? void 0 : block.globalBlock) ?? ""), [getGlobalBlocks, block == null ? void 0 : block.globalBlock]);
5100
+ const blocksAtoms = React.useMemo(() => splitAtom(jotai.atom(globalBlocks)), [globalBlocks]);
5101
+ return /* @__PURE__ */ jsxRuntime.jsx(BlocksRenderer, { splitAtoms: blocksAtoms, blocks: globalBlocks });
4934
5102
  };
4935
5103
  const BlocksRenderer = ({
4936
5104
  blocks,
4937
- filterFn
5105
+ parent = null,
5106
+ splitAtoms = void 0
4938
5107
  }) => {
4939
- const filteredBlocks = React.useMemo(() => lodashEs.filter(blocks, filterFn), [blocks, filterFn]);
4940
- const hasChildren = (blockId) => lodashEs.filter(blocks, (b) => b._parent === blockId).length > 0;
5108
+ const getAtomValue = useGetBlockAtom(splitAtoms);
5109
+ const filteredBlocks = React.useMemo(
5110
+ () => lodashEs.filter(blocks, (block) => lodashEs.isString(parent) ? block._parent === parent : !block._parent),
5111
+ [blocks, parent]
5112
+ );
5113
+ const hasChildren = React.useCallback((block) => lodashEs.filter(blocks, (b) => b._parent === block._id).length > 0, [blocks]);
4941
5114
  return lodashEs.map(filteredBlocks, (block) => {
4942
- return /* @__PURE__ */ jsxRuntime.jsx(BlockRenderer, { blockAtom: block._atom, children: block._type === "GlobalBlock" ? /* @__PURE__ */ jsxRuntime.jsx(GlobalBlocksRenderer, { blockAtom: block._atom }) : hasChildren(block._id) ? /* @__PURE__ */ jsxRuntime.jsx(BlocksRenderer, { blocks, filterFn: (b) => b._parent === block._id }) : null }, block._id);
5115
+ return /* @__PURE__ */ jsxRuntime.jsx(BlockRenderer, { blockAtom: getAtomValue(block._id), children: block._type === "GlobalBlock" ? /* @__PURE__ */ jsxRuntime.jsx(GlobalBlocksRenderer, { blockAtom: getAtomValue(block._id) }) : hasChildren(block) ? /* @__PURE__ */ jsxRuntime.jsx(BlocksRenderer, { splitAtoms, blocks, parent: block._id }) : null }, block._id);
4943
5116
  });
4944
5117
  };
4945
5118
  const PageBlocksRenderer = () => {
4946
5119
  const [blocks] = useBlocksStore();
4947
- return /* @__PURE__ */ jsxRuntime.jsx(BlocksRenderer, { blocks, filterFn: (block) => lodashEs.isEmpty(block._parent) });
5120
+ return /* @__PURE__ */ jsxRuntime.jsx(BlocksRenderer, { blocks });
4948
5121
  };
4949
5122
  const StaticBlocksRenderer = () => {
4950
5123
  const [blocks] = useBlocksStore();
@@ -6156,7 +6329,7 @@ const JSONForm = React.memo(({ blockId, schema, uiSchema, formData, onChange })
6156
6329
  onChange({ formData: formData2 }, id);
6157
6330
  },
6158
6331
  [onChange, selectedLang],
6159
- 400
6332
+ 1e3
6160
6333
  // save only every 5 seconds
6161
6334
  );
6162
6335
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -10882,7 +11055,7 @@ const getParentNodeIds = (blocks, id) => {
10882
11055
  const expandedIdsAtom = jotai.atom([]);
10883
11056
  const useExpandTree = () => {
10884
11057
  const [ids2] = useSelectedBlockIds();
10885
- const pageBlocks = jotai.useAtomValue(pageBlocksAtom);
11058
+ const pageBlocks = jotai.useAtomValue(presentBlocksAtom);
10886
11059
  const [, setExpandedIds] = jotai.useAtom(expandedIdsAtom);
10887
11060
  React.useEffect(() => {
10888
11061
  let expandedIds = [];
@@ -11523,7 +11696,7 @@ const ChaiBuilderComponent = (props) => {
11523
11696
  React.useEffect(() => {
11524
11697
  setTimeout(() => {
11525
11698
  const withDefaults = runtime.syncBlocksWithDefaults(props.blocks || []);
11526
- setAllBlocks(convertToBlocksAtoms(withDefaults));
11699
+ setAllBlocks(withDefaults);
11527
11700
  if (withDefaults && withDefaults.length > 0) {
11528
11701
  postMessage({ type: "blocks-updated", blocks: withDefaults });
11529
11702
  }