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

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,230 @@ 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(splitAtoms);
1845
+ const blockAtom = lodashEs.find(
1846
+ blockAsAtoms,
1847
+ (b) => get(b)._id === (lodashEs.isString(idOrAtom) ? idOrAtom : get(idOrAtom)._id)
1848
+ );
1849
+ if (!blockAtom) {
1850
+ throw new Error(`Block with id ${idOrAtom} not found`);
1851
+ }
1852
+ return get(blockAtom);
1853
+ },
1854
+ [splitAtoms]
1855
+ )
1856
+ );
1857
+ };
1858
+ const useGetBlockAtom = (splitAtoms) => {
1859
+ return useAtomCallback(
1860
+ React.useCallback(
1861
+ (get, _set, idOrAtom) => {
1862
+ const blockAsAtoms = get(splitAtoms);
1863
+ const blockAtom = lodashEs.find(
1864
+ blockAsAtoms,
1865
+ (b) => get(b)._id === (lodashEs.isString(idOrAtom) ? idOrAtom : get(idOrAtom)._id)
1866
+ );
1867
+ if (!blockAtom) {
1868
+ throw new Error(`Block with id ${idOrAtom} not found`);
1869
+ }
1870
+ return blockAtom;
1871
+ },
1872
+ [splitAtoms]
1873
+ )
1874
+ );
1875
+ };
1876
+ function insertBlocksAtPosition(allBlocks, newBlocks, parentId, position) {
1877
+ let parentBlocks = allBlocks.filter((block) => !block._parent);
1878
+ if (parentId) {
1879
+ parentBlocks = allBlocks.filter((block) => block._parent === parentId);
1880
+ }
1881
+ const insertPosition = !isNaN(position) || position > -1 ? Math.min(position, parentBlocks.length) : parentBlocks.length;
1882
+ let insertIndex = allBlocks.length;
1883
+ for (let i = 0, count = 0; i < allBlocks.length; i++) {
1884
+ if (allBlocks[i]._parent === parentId) {
1885
+ if (count === insertPosition) {
1886
+ insertIndex = i;
1887
+ break;
1888
+ }
1889
+ count++;
1890
+ }
1891
+ }
1892
+ if (!parentId && position !== void 0 && position >= parentBlocks.length) {
1893
+ insertIndex = allBlocks.length;
1894
+ }
1895
+ return [...allBlocks.slice(0, insertIndex), ...newBlocks, ...allBlocks.slice(insertIndex)];
1896
+ }
1897
+ function flattenTree(node) {
1898
+ let flatArray = [];
1899
+ node.walk((n) => {
1900
+ delete n.model.children;
1901
+ flatArray.push(n.model);
1902
+ return true;
1903
+ });
1904
+ return flatArray;
1905
+ }
1906
+ function findNodeById(node, id) {
1907
+ return node.first((n) => n.model._id === id) || null;
1908
+ }
1909
+ function moveNode(rootNode, nodeIdToMove, newParentId, position) {
1910
+ const nodeToMove = findNodeById(rootNode, nodeIdToMove);
1911
+ const newParentNode = findNodeById(rootNode, newParentId);
1912
+ if (nodeToMove && newParentNode) {
1913
+ nodeToMove.drop();
1914
+ if (!newParentNode.children) {
1915
+ newParentNode.model.children = [];
1916
+ }
1917
+ try {
1918
+ newParentNode.addChildAtIndex(nodeToMove, position);
1919
+ } catch (error) {
1920
+ console.error("Error adding child to parent:", error);
1921
+ return false;
1922
+ }
1923
+ return true;
1924
+ }
1925
+ return false;
1926
+ }
1927
+ function moveBlocksWithChildren(_blocks, idToMove, newParentId, newPosition) {
1928
+ if (!idToMove) return _blocks;
1929
+ newParentId = newParentId || "root";
1930
+ const tree2 = new TreeModel();
1931
+ const root = tree2.parse({ _id: "root", children: getBlocksTree(_blocks) });
1932
+ if (moveNode(root, idToMove, newParentId, newPosition)) {
1933
+ const newBlocks = flattenTree(root);
1934
+ const movedBlock = newBlocks.find((block) => block._id === idToMove);
1935
+ if (movedBlock) movedBlock._parent = newParentId === "root" ? null : newParentId;
1936
+ newBlocks.shift();
1937
+ return newBlocks;
1938
+ }
1939
+ return _blocks;
1940
+ }
1941
+ const useBlocksStoreManager = () => {
1942
+ const [, setBlocks] = useBlocksStore();
1943
+ const { postMessage } = useBroadcastChannel();
1944
+ const updateBlockAtom = useUpdateBlockAtom();
1945
+ return {
1946
+ setNewBlocks: (newBlocks) => {
1947
+ setBlocks(newBlocks);
1948
+ postMessage({ type: "blocks-updated", blocks: newBlocks });
1949
+ },
1950
+ addBlocks: (newBlocks, parent, position) => {
1951
+ setBlocks((prevBlocks) => {
1952
+ const blocks = insertBlocksAtPosition(prevBlocks, newBlocks, parent, position);
1953
+ postMessage({ type: "blocks-updated", blocks });
1954
+ return blocks;
1955
+ });
1956
+ },
1957
+ removeBlocks: (blockIds) => {
1958
+ setBlocks((prevBlocks) => {
1959
+ const blocks = removeNestedBlocks(prevBlocks, blockIds);
1960
+ postMessage({ type: "blocks-updated", blocks });
1961
+ return blocks;
1962
+ });
1963
+ },
1964
+ moveBlocks: (blockIds, newParent, position) => {
1965
+ setBlocks((prevBlocks) => {
1966
+ let blocks = [...prevBlocks];
1967
+ for (let i = 0; i < blockIds.length; i++) {
1968
+ blocks = moveBlocksWithChildren(blocks, blockIds[i], newParent, position);
1969
+ }
1970
+ lodashEs.each(blockIds, (id) => {
1971
+ const block = lodashEs.find(blocks, (b) => b._id === id);
1972
+ if (block) {
1973
+ updateBlockAtom({ id, props: { _parent: block._parent || null } });
1974
+ }
1975
+ });
1976
+ postMessage({ type: "blocks-updated", blocks });
1977
+ return blocks;
1978
+ });
1979
+ },
1980
+ updateBlocksProps: (blocks) => {
1981
+ blocks.forEach((block) => {
1982
+ const updatedBlock = lodashEs.omit(block, "_id");
1983
+ updateBlockAtom({ id: block._id, props: updatedBlock });
1984
+ });
1985
+ postMessage({ type: "blocks-props-updated", blocks });
1986
+ }
1987
+ };
1988
+ };
1829
1989
  const useBlocksStore = () => {
1830
- return jotai.useAtom(pageBlocksAtom);
1990
+ return jotai.useAtom(presentBlocksAtom);
1831
1991
  };
1832
1992
  const useBlocksStoreUndoableActions = () => {
1833
1993
  const { add } = useUndoManager();
@@ -1961,7 +2121,7 @@ const useAddBlock = () => {
1961
2121
  blocks[0]._parent = parentBlock._parent;
1962
2122
  parentBlockId = parentBlock._parent;
1963
2123
  }
1964
- addBlocks(convertToBlocksAtoms(blocks), parentBlockId, position);
2124
+ addBlocks(blocks, parentBlockId, position);
1965
2125
  setSelected([(_a = lodashEs.first(blocks)) == null ? void 0 : _a._id]);
1966
2126
  return lodashEs.first(blocks);
1967
2127
  },
@@ -1993,7 +2153,7 @@ const useAddBlock = () => {
1993
2153
  parentBlockId = parentBlock._parent;
1994
2154
  }
1995
2155
  const newBlocks = [newBlock];
1996
- addBlocks(convertToBlocksAtoms(newBlocks), parentBlockId, position);
2156
+ addBlocks(newBlocks, parentBlockId, position);
1997
2157
  setSelected([newBlock._id]);
1998
2158
  return newBlock;
1999
2159
  },
@@ -3191,9 +3351,12 @@ const selectedStylingBlocksAtom = jotai.atom([]);
3191
3351
  selectedStylingBlocksAtom.debugLabel = "selectedStylingBlocksAtom";
3192
3352
  const useSelectedStylingBlocks = () => jotai.useAtom(selectedStylingBlocksAtom);
3193
3353
  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
3354
+ const blockAtoms = lodashEs.filter(
3355
+ get(pageBlocksAtomsAtom),
3356
+ (blockAtom) => (
3357
+ // @ts-ignore
3358
+ blockIds.includes(get(blockAtom)._id)
3359
+ )
3197
3360
  );
3198
3361
  const styleBlock = lodashEs.first(get(selectedStylingBlocksAtom));
3199
3362
  return lodashEs.map(blockAtoms, (blockAtom) => {
@@ -3307,7 +3470,7 @@ const useDuplicateBlocks = () => {
3307
3470
  const blockPosition = siblingBlocks.indexOf(block);
3308
3471
  const newBlockPosition = blockPosition + 1;
3309
3472
  const newBlocks = getDuplicatedBlocks(presentBlocks, blockId, parentId);
3310
- addBlocks(convertToBlocksAtoms(newBlocks), parentId, newBlockPosition);
3473
+ addBlocks(newBlocks, parentId, newBlockPosition);
3311
3474
  newBlockIds.push(lodashEs.get(newBlocks, "0._id", ""));
3312
3475
  });
3313
3476
  setSelected(newBlockIds);
@@ -3341,7 +3504,7 @@ const useCanPaste = () => {
3341
3504
  };
3342
3505
  };
3343
3506
  const useMoveCutBlocks = () => {
3344
- const presentBlocks = jotai.useAtomValue(pageBlocksAtom);
3507
+ const presentBlocks = jotai.useAtomValue(presentBlocksAtom);
3345
3508
  const { moveBlocks: moveBlocks2 } = useBlocksStoreUndoableActions();
3346
3509
  return React.useCallback(
3347
3510
  (blockIds, newParentId) => {
@@ -3419,9 +3582,12 @@ const usePreviewMode = () => {
3419
3582
  };
3420
3583
  const removeClassFromBlocksAtom = jotai.atom(null, (get, _set, { blockIds, fullClasses }) => {
3421
3584
  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
3585
+ const blockAtoms = lodashEs.filter(
3586
+ get(pageBlocksAtomsAtom),
3587
+ (blockAtom) => (
3588
+ // @ts-ignore
3589
+ blockIds.includes(get(blockAtom)._id)
3590
+ )
3425
3591
  );
3426
3592
  return lodashEs.map(blockAtoms, (blockAtom) => {
3427
3593
  const block = get(blockAtom);
@@ -3624,23 +3790,27 @@ const useBlockHighlight = () => {
3624
3790
  var _a;
3625
3791
  return (iframe == null ? void 0 : iframe.contentDocument) || ((_a = iframe == null ? void 0 : iframe.contentWindow) == null ? void 0 : _a.document);
3626
3792
  }, [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;
3793
+ const highlightBlock = React.useCallback(
3794
+ (elementOrID) => {
3795
+ if (!innerDoc) return;
3796
+ if (lastHighlighted) {
3797
+ lastHighlighted.removeAttribute("data-highlighted");
3798
+ }
3799
+ if (typeof elementOrID !== "string") {
3800
+ elementOrID.setAttribute("data-highlighted", "true");
3801
+ lastHighlighted = elementOrID;
3802
+ } else if (typeof elementOrID === "string") {
3803
+ const element = innerDoc.querySelector(`[data-block-id="${elementOrID}"]`);
3804
+ if (element) {
3805
+ element.setAttribute("data-highlighted", "true");
3806
+ lastHighlighted = element;
3807
+ }
3808
+ } else {
3809
+ lastHighlighted = null;
3639
3810
  }
3640
- } else {
3641
- lastHighlighted = null;
3642
- }
3643
- };
3811
+ },
3812
+ [innerDoc]
3813
+ );
3644
3814
  const clearHighlight = () => {
3645
3815
  if (lastHighlighted) {
3646
3816
  lastHighlighted.removeAttribute("data-highlighted");
@@ -3653,7 +3823,7 @@ const globalBlocksStoreAtom = atom({});
3653
3823
  const globalBlocksLoadingStateAtom = atom({});
3654
3824
  const useGlobalBlocksStore = () => {
3655
3825
  const [globalBlocks, setGlobalBlocks] = useAtom(globalBlocksStoreAtom);
3656
- const getGlobalBlocks = React.useCallback((globalBlockId) => lodashEs.get(globalBlocks, globalBlockId, []), [globalBlocks]);
3826
+ const getGlobalBlocks = React.useCallback((globalBlock) => lodashEs.get(globalBlocks, globalBlock, []), [globalBlocks]);
3657
3827
  const reset = React.useCallback(() => setGlobalBlocks({}), [setGlobalBlocks]);
3658
3828
  return { getGlobalBlocks, reset };
3659
3829
  };
@@ -3661,14 +3831,10 @@ const useWatchGlobalBlocks = () => {
3661
3831
  const [blocksStore] = useBlocksStore();
3662
3832
  const [globalBlocks, setGlobalBlocks] = useAtom(globalBlocksStoreAtom);
3663
3833
  const [globalBlocksLoadingState, setGlobalBlocksLoadingState] = useAtom(globalBlocksLoadingStateAtom);
3664
- const getBlockAtomValue = useGetBlockAtomValue();
3665
3834
  const getGlobalBlockBlocks = useBuilderProp("getGlobalBlockBlocks", async (_key) => []);
3666
3835
  const globalBlocksList = React.useMemo(() => {
3667
3836
  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
- });
3837
+ return globalBlocks2.filter((block) => block._type === "GlobalBlock").map((block) => block.globalBlock);
3672
3838
  }, [blocksStore]);
3673
3839
  React.useEffect(() => {
3674
3840
  lodashEs.forEach(globalBlocksList, (globalBlock) => {
@@ -4070,7 +4236,7 @@ const useAiAssistant = () => {
4070
4236
  };
4071
4237
  const wrapperBlockAtom = jotai.atom((get) => {
4072
4238
  var _a;
4073
- const blocks = get(pageBlocksAtom);
4239
+ const blocks = get(presentBlocksAtom);
4074
4240
  const blockIds = get(selectedBlockIdsAtom);
4075
4241
  const blockId = blockIds.length === 1 ? blockIds[0] : null;
4076
4242
  if (!blockId) return null;
@@ -4547,7 +4713,7 @@ const useHandleCanvasDblClick = () => {
4547
4713
  const updateContent = useUpdateBlocksProps();
4548
4714
  const [editingBlockId, setEditingBlockId] = jotai.useAtom(inlineEditingActiveAtom);
4549
4715
  const { clearHighlight } = useBlockHighlight();
4550
- const getBlockAtomValue = useGetBlockAtomValue();
4716
+ const getBlockAtomValue = useGetBlockAtomValue(pageBlocksAtomsAtom);
4551
4717
  return React.useCallback(
4552
4718
  (e2) => {
4553
4719
  var _a;
@@ -4928,23 +5094,28 @@ const BlockRenderer = ({ blockAtom, children }) => {
4928
5094
  const GlobalBlocksRenderer = ({ blockAtom }) => {
4929
5095
  const { getGlobalBlocks } = useGlobalBlocksStore();
4930
5096
  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) });
5097
+ const globalBlocks = React.useMemo(() => getGlobalBlocks((block == null ? void 0 : block.globalBlock) ?? ""), [getGlobalBlocks, block == null ? void 0 : block.globalBlock]);
5098
+ const blocksAtoms = React.useMemo(() => splitAtom(jotai.atom(globalBlocks)), [globalBlocks]);
5099
+ return /* @__PURE__ */ jsxRuntime.jsx(BlocksRenderer, { splitAtoms: blocksAtoms, blocks: globalBlocks });
4934
5100
  };
4935
5101
  const BlocksRenderer = ({
4936
5102
  blocks,
4937
- filterFn
5103
+ parent = null,
5104
+ splitAtoms = void 0
4938
5105
  }) => {
4939
- const filteredBlocks = React.useMemo(() => lodashEs.filter(blocks, filterFn), [blocks, filterFn]);
4940
- const hasChildren = (blockId) => lodashEs.filter(blocks, (b) => b._parent === blockId).length > 0;
5106
+ const getAtomValue = useGetBlockAtom(splitAtoms);
5107
+ const filteredBlocks = React.useMemo(
5108
+ () => lodashEs.filter(blocks, (block) => lodashEs.isString(parent) ? block._parent === parent : !block._parent),
5109
+ [blocks, parent]
5110
+ );
5111
+ const hasChildren = React.useCallback((block) => lodashEs.filter(blocks, (b) => b._parent === block._id).length > 0, [blocks]);
4941
5112
  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);
5113
+ 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
5114
  });
4944
5115
  };
4945
5116
  const PageBlocksRenderer = () => {
4946
5117
  const [blocks] = useBlocksStore();
4947
- return /* @__PURE__ */ jsxRuntime.jsx(BlocksRenderer, { blocks, filterFn: (block) => lodashEs.isEmpty(block._parent) });
5118
+ return /* @__PURE__ */ jsxRuntime.jsx(BlocksRenderer, { splitAtoms: pageBlocksAtomsAtom, blocks });
4948
5119
  };
4949
5120
  const StaticBlocksRenderer = () => {
4950
5121
  const [blocks] = useBlocksStore();
@@ -6156,7 +6327,7 @@ const JSONForm = React.memo(({ blockId, schema, uiSchema, formData, onChange })
6156
6327
  onChange({ formData: formData2 }, id);
6157
6328
  },
6158
6329
  [onChange, selectedLang],
6159
- 400
6330
+ 1e3
6160
6331
  // save only every 5 seconds
6161
6332
  );
6162
6333
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -8929,7 +9100,8 @@ const ChaiBuilderBlocks = ({ groups, blocks, parentId, position, gridCols = "gri
8929
9100
  position,
8930
9101
  block,
8931
9102
  disabled: !canAcceptChildBlock(parentType, block.type) || !canBeNestedInside(parentType, block.type)
8932
- }
9103
+ },
9104
+ block.type
8933
9105
  ))
8934
9106
  ) })
8935
9107
  ] }, group)) }) })
@@ -10882,7 +11054,7 @@ const getParentNodeIds = (blocks, id) => {
10882
11054
  const expandedIdsAtom = jotai.atom([]);
10883
11055
  const useExpandTree = () => {
10884
11056
  const [ids2] = useSelectedBlockIds();
10885
- const pageBlocks = jotai.useAtomValue(pageBlocksAtom);
11057
+ const pageBlocks = jotai.useAtomValue(presentBlocksAtom);
10886
11058
  const [, setExpandedIds] = jotai.useAtom(expandedIdsAtom);
10887
11059
  React.useEffect(() => {
10888
11060
  let expandedIds = [];
@@ -11523,7 +11695,7 @@ const ChaiBuilderComponent = (props) => {
11523
11695
  React.useEffect(() => {
11524
11696
  setTimeout(() => {
11525
11697
  const withDefaults = runtime.syncBlocksWithDefaults(props.blocks || []);
11526
- setAllBlocks(convertToBlocksAtoms(withDefaults));
11698
+ setAllBlocks(withDefaults);
11527
11699
  if (withDefaults && withDefaults.length > 0) {
11528
11700
  postMessage({ type: "blocks-updated", blocks: withDefaults });
11529
11701
  }