@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.js CHANGED
@@ -6,7 +6,7 @@ import * as React from "react";
6
6
  import React__default, { createContext, useReducer, useEffect, useDebugValue, useCallback, useContext, useMemo, Component, Children, useState, useRef, Suspense, createElement, memo, lazy } from "react";
7
7
  import { ag as useToast, S as Skeleton, B as Button, L as Label, D as Dialog, s as DialogTrigger, a as DialogContent, h as Badge, T as Textarea, O as Tooltip, P as TooltipTrigger, Q as TooltipContent, V as Popover, W as PopoverTrigger, X as PopoverContent, I as Input$1, U as TooltipPortal, e as AccordionItem, f as AccordionTrigger, g as AccordionContent, $ as DropdownMenu, a0 as DropdownMenuTrigger, a1 as DropdownMenuContent, G as ScrollArea, a5 as DropdownMenuLabel, a6 as DropdownMenuSeparator, a8 as DropdownMenuGroup, a2 as DropdownMenuItem, a7 as DropdownMenuShortcut, A as Accordion, C as Card, x as CardHeader, E as CardDescription, F as CardContent, y as CardFooter, J as Tabs, K as TabsList, M as TabsTrigger, N as TabsContent, aj as ContextMenu, ak as ContextMenuTrigger, al as ContextMenuContent, am as ContextMenuItem, j as AlertDialog, k as AlertDialogTrigger, l as AlertDialogContent, m as AlertDialogHeader, o as AlertDialogTitle, p as AlertDialogDescription, n as AlertDialogFooter, r as AlertDialogCancel, q as AlertDialogAction, a3 as DropdownMenuCheckboxItem, Y as HoverCard, Z as HoverCardTrigger, _ as HoverCardContent, b as Switch, ae as Separator, R as TooltipProvider, ai as Toaster } from "./context-menu-DHla8ofZ.js";
8
8
  import { atom as atom$1, useAtomValue as useAtomValue$1, useAtom as useAtom$1, useSetAtom as useSetAtom$1, getDefaultStore as getDefaultStore$1 } from "jotai";
9
- import { find, filter, flatten, map, omit, isString, has, get, includes, first, without, compact, isEmpty, each, set, isObject, memoize, noop, keys, range, values, flattenDeep, startsWith, isNull, forEach, unset, chunk, cloneDeep, pick, throttle, isFunction, reverse, startCase, debounce, capitalize, split, findIndex, take, nth, toLower, isNumber, parseInt as parseInt$1, isNaN as isNaN$1, findLast, intersection, groupBy, uniq, flatMapDeep, some, reject, sortBy, toUpper, round } from "lodash-es";
9
+ import { has, get, find, filter, flatten, map, omit, isString, includes, without, compact, each, set, first, isObject, memoize, isEmpty, noop, keys, range, values, flattenDeep, startsWith, isNull, forEach, unset, chunk, cloneDeep, pick, throttle, isFunction as isFunction$1, reverse, startCase, debounce, capitalize, split, findIndex, take, nth, toLower, isNumber, parseInt as parseInt$1, isNaN as isNaN$1, findLast, intersection, groupBy, uniq, flatMapDeep, some, reject, sortBy, toUpper, round } from "lodash-es";
10
10
  import { Provider } from "react-wrap-balancer";
11
11
  import { g as generateUUID, a as getBreakpointValue, c as cn, G as GenIcon } from "./iconBase-CWgVxu0A.js";
12
12
  import { useTranslation, initReactI18next } from "react-i18next";
@@ -14,12 +14,12 @@ import { useTranslation as useTranslation2 } from "react-i18next";
14
14
  import { flip } from "@floating-ui/dom";
15
15
  import { useFloating, shift } from "@floating-ui/react-dom";
16
16
  import { ArrowUpIcon, PlusIcon, CopyIcon, TrashIcon, DragHandleDots2Icon, BoxModelIcon, ReaderIcon, DropdownMenuIcon, BoxIcon, DragHandleHorizontalIcon, ViewHorizontalIcon, BorderAllIcon, BorderTopIcon, TableIcon, RadiobuttonIcon, InputIcon, ButtonIcon, CheckboxIcon, GroupIcon, SpaceBetweenVerticallyIcon, ColumnsIcon, TextIcon, RowsIcon, SketchLogoIcon, DividerHorizontalIcon, CodeIcon, CursorTextIcon, VideoIcon, Link1Icon, HeadingIcon, ImageIcon, Cross2Icon, EyeOpenIcon, EyeClosedIcon, WidthIcon, HeightIcon, ArrowRightIcon, ArrowDownIcon, ArrowLeftIcon, ArrowTopLeftIcon, ArrowTopRightIcon, ArrowBottomRightIcon, ArrowBottomLeftIcon, AlignLeftIcon, AlignCenterHorizontallyIcon, AlignRightIcon, StretchHorizontallyIcon, FontItalicIcon, UnderlineIcon, OverlineIcon, LetterCaseUppercaseIcon, Cross1Icon, InfoCircledIcon, MinusIcon, TriangleDownIcon, RowSpacingIcon, CrossCircledIcon, CaretDownIcon, CaretRightIcon, CardStackIcon, CardStackPlusIcon, ScissorsIcon, CheckIcon, DotsVerticalIcon, MobileIcon, LaptopIcon, DesktopIcon, SunIcon, ResetIcon, EraserIcon, ZoomInIcon, MixerHorizontalIcon, LightningBoltIcon } from "@radix-ui/react-icons";
17
- import { useDebouncedCallback, useThrottledCallback, useResizeObserver, useIntervalEffect } from "@react-hookz/web";
17
+ import { useThrottledCallback, useDebouncedCallback, useResizeObserver, useIntervalEffect } from "@react-hookz/web";
18
18
  import { useFeature, FlagsProvider } from "flagged";
19
19
  import { getRegisteredChaiBlock, getDefaultBlockProps, useRegisteredChaiBlocks, getBlockFormSchemas, syncBlocksWithDefaults } from "@chaibuilder/runtime";
20
20
  import { registerChaiBlock } from "@chaibuilder/runtime";
21
- import TreeModel from "tree-model";
22
21
  import { e as getDefaultExportFromCjs, d as defaultThemeOptions, g as getChaiThemeOptions, p as plugin, a as getChaiThemeCssVariables, c as getThemeFontsLinkMarkup } from "./ChaiThemeFn-DzirXKjI.js";
22
+ import TreeModel from "tree-model";
23
23
  import { useHotkeys } from "react-hotkeys-hook";
24
24
  import { PlusIcon as PlusIcon$1, PanelRightClose, PanelRightOpen, AppWindowIcon, AlignHorizontalJustifyStart, UnfoldHorizontal, DatabaseIcon, Columns, Rows, GlobeIcon, ChevronRight, X, Plus, ChevronLeft, PlusCircle, ChevronDown, List, Loader, SparklesIcon, EyeOff, Eye, SmileIcon, ShuffleIcon, DatabaseZapIcon, Edit2, Paintbrush, Layers } from "lucide-react";
25
25
  import ReactQuill, { Quill } from "react-quill";
@@ -571,6 +571,142 @@ const getDefaultStore = () => {
571
571
  const RESET = Symbol(
572
572
  ""
573
573
  );
574
+ const getCached$1 = (c, m, k) => (m.has(k) ? m : m.set(k, c())).get(k);
575
+ const cache1$2 = /* @__PURE__ */ new WeakMap();
576
+ const memo2$1 = (create, dep1, dep2) => {
577
+ const cache2 = getCached$1(() => /* @__PURE__ */ new WeakMap(), cache1$2, dep1);
578
+ return getCached$1(create, cache2, dep2);
579
+ };
580
+ const cacheKeyForEmptyKeyExtractor = {};
581
+ const isWritable = (atom2) => !!atom2.write;
582
+ const isFunction = (x) => typeof x === "function";
583
+ function splitAtom(arrAtom, keyExtractor) {
584
+ return memo2$1(
585
+ () => {
586
+ const mappingCache = /* @__PURE__ */ new WeakMap();
587
+ const getMapping = (arr, prev) => {
588
+ let mapping = mappingCache.get(arr);
589
+ if (mapping) {
590
+ return mapping;
591
+ }
592
+ const prevMapping = prev && mappingCache.get(prev);
593
+ const atomList = [];
594
+ const keyList = [];
595
+ arr.forEach((item, index) => {
596
+ const key = index;
597
+ keyList[index] = key;
598
+ const cachedAtom = prevMapping && prevMapping.atomList[prevMapping.keyList.indexOf(key)];
599
+ if (cachedAtom) {
600
+ atomList[index] = cachedAtom;
601
+ return;
602
+ }
603
+ const read = (get2) => {
604
+ const prev2 = get2(mappingAtom);
605
+ const currArr = get2(arrAtom);
606
+ const mapping2 = getMapping(currArr, prev2 == null ? void 0 : prev2.arr);
607
+ const index2 = mapping2.keyList.indexOf(key);
608
+ if (index2 < 0 || index2 >= currArr.length) {
609
+ const prevItem = arr[getMapping(arr).keyList.indexOf(key)];
610
+ if (prevItem) {
611
+ return prevItem;
612
+ }
613
+ throw new Error("splitAtom: index out of bounds for read");
614
+ }
615
+ return currArr[index2];
616
+ };
617
+ const write = (get2, set2, update) => {
618
+ const prev2 = get2(mappingAtom);
619
+ const arr2 = get2(arrAtom);
620
+ const mapping2 = getMapping(arr2, prev2 == null ? void 0 : prev2.arr);
621
+ const index2 = mapping2.keyList.indexOf(key);
622
+ if (index2 < 0 || index2 >= arr2.length) {
623
+ throw new Error("splitAtom: index out of bounds for write");
624
+ }
625
+ const nextItem = isFunction(update) ? update(arr2[index2]) : update;
626
+ if (!Object.is(arr2[index2], nextItem)) {
627
+ set2(arrAtom, [
628
+ ...arr2.slice(0, index2),
629
+ nextItem,
630
+ ...arr2.slice(index2 + 1)
631
+ ]);
632
+ }
633
+ };
634
+ atomList[index] = isWritable(arrAtom) ? atom(read, write) : atom(read);
635
+ });
636
+ if (prevMapping && prevMapping.keyList.length === keyList.length && prevMapping.keyList.every((x, i) => x === keyList[i])) {
637
+ mapping = prevMapping;
638
+ } else {
639
+ mapping = { arr, atomList, keyList };
640
+ }
641
+ mappingCache.set(arr, mapping);
642
+ return mapping;
643
+ };
644
+ const mappingAtom = atom((get2) => {
645
+ const prev = get2(mappingAtom);
646
+ const arr = get2(arrAtom);
647
+ const mapping = getMapping(arr, prev == null ? void 0 : prev.arr);
648
+ return mapping;
649
+ });
650
+ mappingAtom.init = void 0;
651
+ const splittedAtom = isWritable(arrAtom) ? atom(
652
+ (get2) => get2(mappingAtom).atomList,
653
+ (get2, set2, action) => {
654
+ switch (action.type) {
655
+ case "remove": {
656
+ const index = get2(splittedAtom).indexOf(action.atom);
657
+ if (index >= 0) {
658
+ const arr = get2(arrAtom);
659
+ set2(arrAtom, [
660
+ ...arr.slice(0, index),
661
+ ...arr.slice(index + 1)
662
+ ]);
663
+ }
664
+ break;
665
+ }
666
+ case "insert": {
667
+ const index = action.before ? get2(splittedAtom).indexOf(action.before) : get2(splittedAtom).length;
668
+ if (index >= 0) {
669
+ const arr = get2(arrAtom);
670
+ set2(arrAtom, [
671
+ ...arr.slice(0, index),
672
+ action.value,
673
+ ...arr.slice(index)
674
+ ]);
675
+ }
676
+ break;
677
+ }
678
+ case "move": {
679
+ const index1 = get2(splittedAtom).indexOf(action.atom);
680
+ const index2 = action.before ? get2(splittedAtom).indexOf(action.before) : get2(splittedAtom).length;
681
+ if (index1 >= 0 && index2 >= 0) {
682
+ const arr = get2(arrAtom);
683
+ if (index1 < index2) {
684
+ set2(arrAtom, [
685
+ ...arr.slice(0, index1),
686
+ ...arr.slice(index1 + 1, index2),
687
+ arr[index1],
688
+ ...arr.slice(index2)
689
+ ]);
690
+ } else {
691
+ set2(arrAtom, [
692
+ ...arr.slice(0, index2),
693
+ arr[index1],
694
+ ...arr.slice(index2, index1),
695
+ ...arr.slice(index1 + 1)
696
+ ]);
697
+ }
698
+ }
699
+ break;
700
+ }
701
+ }
702
+ }
703
+ ) : atom((get2) => get2(mappingAtom).atomList);
704
+ return splittedAtom;
705
+ },
706
+ arrAtom,
707
+ cacheKeyForEmptyKeyExtractor
708
+ );
709
+ }
574
710
  const isPromiseLike$1 = (x) => typeof (x == null ? void 0 : x.then) === "function";
575
711
  function createJSONStorage(getStringStorage = () => {
576
712
  try {
@@ -963,10 +1099,61 @@ __publicField(Frame, "defaultProps", {
963
1099
  initialContent: '<!DOCTYPE html><html><head></head><body><div class="frame-root"></div></body></html>'
964
1100
  });
965
1101
  const ChaiFrame = React__default.forwardRef((props, ref) => /* @__PURE__ */ jsx(Frame, { ...props, forwardedRef: ref }));
1102
+ const canAcceptChildBlock = (parentType, childType) => {
1103
+ if (!parentType) return true;
1104
+ const blockDefinition = getRegisteredChaiBlock(parentType);
1105
+ if (!blockDefinition) return false;
1106
+ return has(blockDefinition, "canAcceptBlock") ? blockDefinition.canAcceptBlock(childType) : false;
1107
+ };
1108
+ const canAddChildBlock = (parentType) => {
1109
+ const blockDefinition = getRegisteredChaiBlock(parentType);
1110
+ if (!blockDefinition) return false;
1111
+ return has(blockDefinition, "canAcceptBlock");
1112
+ };
1113
+ const canBeNestedInside = (parentType, childType) => {
1114
+ const blockDefinition = getRegisteredChaiBlock(childType);
1115
+ if (!blockDefinition) return true;
1116
+ return has(blockDefinition, "canBeNested") ? blockDefinition.canBeNested(parentType) : true;
1117
+ };
1118
+ const canDuplicateBlock = (type) => {
1119
+ const blockDefinition = getRegisteredChaiBlock(type);
1120
+ if (!blockDefinition) return true;
1121
+ return has(blockDefinition, "canDuplicate") ? blockDefinition.canDuplicate() : true;
1122
+ };
1123
+ const canDeleteBlock = (type) => {
1124
+ const blockDefinition = getRegisteredChaiBlock(type);
1125
+ if (!blockDefinition) return true;
1126
+ return has(blockDefinition, "canDelete") ? blockDefinition.canDelete() : true;
1127
+ };
1128
+ const canDropBlock = (_currentTree, { dragSource, dropTarget: dropTarget2 }) => {
1129
+ const dragSourceType = get(dragSource, "data._type", "");
1130
+ const dropTargetType = get(dropTarget2, "data._type", "");
1131
+ return canAcceptChildBlock(dropTargetType, dragSourceType);
1132
+ };
1133
+ if (import.meta.vitest) {
1134
+ describe("canDropBlock Function", () => {
1135
+ it('should return false if dragSourceType is "Slot"', () => {
1136
+ const dragSource = { data: { _type: "Slot" } };
1137
+ const dropTarget2 = { data: {} };
1138
+ expect(canDropBlock({}, { dragSource, dropTarget: dropTarget2 })).toBe(true);
1139
+ });
1140
+ it("should return true if dropTargetType is empty", () => {
1141
+ const dragSource = { data: { _type: "Box" } };
1142
+ const dropTarget2 = { data: {} };
1143
+ expect(canDropBlock({}, { dragSource, dropTarget: dropTarget2 })).toBe(true);
1144
+ });
1145
+ });
1146
+ }
966
1147
  function duplicateBlocks(blocks, id, _parent) {
967
1148
  const children = filter(blocks, (c) => c._parent === id);
968
1149
  const newBlocks = [];
969
1150
  for (let i = 0; i < children.length; i++) {
1151
+ const slots = getSlots(children[i]);
1152
+ if (Object.keys(slots).length > 0) {
1153
+ Object.keys(slots).forEach((key) => {
1154
+ children[i][key] = `slot:${generateUUID()}`;
1155
+ });
1156
+ }
970
1157
  if (filter(blocks, { _parent: children[i]._id }).length > 0) {
971
1158
  const newId = generateUUID();
972
1159
  newBlocks.push({ ...children[i], oldId: children[i]._id, ...{ _id: newId, _parent } });
@@ -1031,21 +1218,15 @@ const getDuplicatedBlocks = (currentBlocks, id, newParentId = null) => {
1031
1218
  return omit(newBlock, ["global", "oldId"]);
1032
1219
  });
1033
1220
  };
1034
- const pageBlocksAtom = atom$1([]);
1035
- pageBlocksAtom.debugLabel = "pageBlocksAtom";
1036
- const convertToBlocksAtoms = (blocks) => {
1037
- return blocks.map((block) => ({
1038
- _type: block._type,
1039
- _id: block._id,
1040
- _parent: block._parent ?? null,
1041
- _atom: atom$1(block)
1042
- }));
1043
- };
1221
+ const presentBlocksAtom = atom$1([]);
1222
+ presentBlocksAtom.debugLabel = "presentBlocksAtom";
1044
1223
  const treeDSBlocks = atom$1((get2) => {
1045
- const presentBlocks = get2(pageBlocksAtom).map((block) => get2(block._atom));
1046
- return convertToBlocksTree(presentBlocks);
1224
+ const presentBlocks = get2(presentBlocksAtom);
1225
+ return convertToBlocksTree([...presentBlocks]);
1047
1226
  });
1048
1227
  treeDSBlocks.debugLabel = "treeDSBlocks";
1228
+ const pageBlocksAtomsAtom = splitAtom(presentBlocksAtom);
1229
+ pageBlocksAtomsAtom.debugLabel = "pageBlocksAtomsAtom";
1049
1230
  const builderActivePageAtom = atom$1("");
1050
1231
  builderActivePageAtom.debugLabel = "builderActivePageAtom";
1051
1232
  const destinationDropIndexAtom = atom$1(-1);
@@ -1057,87 +1238,10 @@ const globalBlocksAtom = atom$1((get2) => {
1057
1238
  return filter(globalBlocks, (block) => has(block, "blockId"));
1058
1239
  });
1059
1240
  globalBlocksAtom.debugLabel = "globalBlocksAtom";
1060
- const canAcceptChildBlock = (parentType, childType) => {
1061
- if (!parentType) return true;
1062
- const blockDefinition = getRegisteredChaiBlock(parentType);
1063
- if (!blockDefinition) return false;
1064
- return has(blockDefinition, "canAcceptBlock") ? blockDefinition.canAcceptBlock(childType) : false;
1065
- };
1066
- const canAddChildBlock = (parentType) => {
1067
- const blockDefinition = getRegisteredChaiBlock(parentType);
1068
- if (!blockDefinition) return false;
1069
- return has(blockDefinition, "canAcceptBlock");
1070
- };
1071
- const canBeNestedInside = (parentType, childType) => {
1072
- const blockDefinition = getRegisteredChaiBlock(childType);
1073
- if (!blockDefinition) return true;
1074
- return has(blockDefinition, "canBeNested") ? blockDefinition.canBeNested(parentType) : true;
1075
- };
1076
- const canDuplicateBlock = (type) => {
1077
- const blockDefinition = getRegisteredChaiBlock(type);
1078
- if (!blockDefinition) return true;
1079
- return has(blockDefinition, "canDuplicate") ? blockDefinition.canDuplicate() : true;
1080
- };
1081
- const canDeleteBlock = (type) => {
1082
- const blockDefinition = getRegisteredChaiBlock(type);
1083
- if (!blockDefinition) return true;
1084
- return has(blockDefinition, "canDelete") ? blockDefinition.canDelete() : true;
1085
- };
1086
- const canDropBlock = (_currentTree, { dragSource, dropTarget: dropTarget2 }) => {
1087
- const dragSourceType = get(dragSource, "data._type", "");
1088
- const dropTargetType = get(dropTarget2, "data._type", "");
1089
- return canAcceptChildBlock(dropTargetType, dragSourceType);
1090
- };
1091
- if (import.meta.vitest) {
1092
- describe("canDropBlock Function", () => {
1093
- it('should return false if dragSourceType is "Slot"', () => {
1094
- const dragSource = { data: { _type: "Slot" } };
1095
- const dropTarget2 = { data: {} };
1096
- expect(canDropBlock({}, { dragSource, dropTarget: dropTarget2 })).toBe(true);
1097
- });
1098
- it("should return true if dropTargetType is empty", () => {
1099
- const dragSource = { data: { _type: "Box" } };
1100
- const dropTarget2 = { data: {} };
1101
- expect(canDropBlock({}, { dragSource, dropTarget: dropTarget2 })).toBe(true);
1102
- });
1103
- });
1104
- }
1105
- const broadcastChannel = new BroadcastChannel("chaibuilder");
1106
- const useBroadcastChannel = () => {
1107
- const pageId = useBuilderProp("pageId", "chaibuilder_page");
1108
- const postMessage = useDebouncedCallback(
1109
- (message) => broadcastChannel.postMessage({ ...message, pageId }),
1110
- [pageId],
1111
- 200
1112
- );
1113
- return { postMessage };
1114
- };
1115
- const useUnmountBroadcastChannel = () => {
1116
- const [, setBlocks] = useBlocksStore();
1117
- const pageId = useBuilderProp("pageId", "chaibuilder_page");
1118
- const { updateBlocksProps } = useBlocksStoreManager();
1119
- useEffect(() => {
1120
- broadcastChannel.onmessageerror = (event) => {
1121
- console.log("error", event);
1122
- };
1123
- broadcastChannel.onmessage = (event) => {
1124
- if (event.data.type === "blocks-updated" && event.data.pageId === pageId) {
1125
- setBlocks(event.data.blocks);
1126
- }
1127
- if (event.data.type === "blocks-props-updated" && event.data.pageId === pageId) {
1128
- updateBlocksProps(event.data.blocks);
1129
- }
1130
- };
1131
- return () => {
1132
- broadcastChannel.onmessage = null;
1133
- broadcastChannel.onmessageerror = null;
1134
- };
1135
- }, [setBlocks, pageId]);
1136
- };
1137
1241
  const selectedBlockIdsAtom = atom$1([]);
1138
1242
  selectedBlockIdsAtom.debugLabel = "selectedBlockIdsAtom";
1139
1243
  const selectedBlocksAtom = atom$1((get2) => {
1140
- const blocks = get2(pageBlocksAtom);
1244
+ const blocks = get2(presentBlocksAtom);
1141
1245
  const blockIds = get2(selectedBlockIdsAtom);
1142
1246
  return map(
1143
1247
  filter(blocks, ({ _id }) => includes(blockIds, _id)),
@@ -1151,7 +1255,7 @@ const selectedBlockAtom = atom$1((get2) => {
1151
1255
  return null;
1152
1256
  }
1153
1257
  if (blocks.length === 1) {
1154
- return get2(first(blocks)._atom);
1258
+ return blocks[0];
1155
1259
  }
1156
1260
  });
1157
1261
  selectedBlockAtom.debugLabel = "selectedBlockAtom";
@@ -1159,7 +1263,7 @@ const getParentId = (block) => get(block, "_parent", null);
1159
1263
  const selectedBlocksParentsAtom = atom$1((get2) => {
1160
1264
  const selectedBlocks = get2(selectedBlocksAtom);
1161
1265
  const parentIds = map(selectedBlocks, getParentId);
1162
- return filter(get2(pageBlocksAtom), (block) => includes(parentIds, block._id));
1266
+ return filter(get2(presentBlocksAtom), (block) => includes(parentIds, block._id));
1163
1267
  });
1164
1268
  selectedBlocksParentsAtom.debugLabel = "selectedBlocksParentsAtom";
1165
1269
  const selectedBlockFlexChildAtom = atom$1(() => {
@@ -1181,7 +1285,7 @@ const useSelectedBlocksDisplayChild = () => ({
1181
1285
  const useSelectedBlock = () => useAtomValue$1(selectedBlockAtom);
1182
1286
  const selectedBlockHierarchy = atom$1((get2) => {
1183
1287
  const selectedBlock = get2(selectedBlockAtom);
1184
- const allBlocks = get2(pageBlocksAtom);
1288
+ const allBlocks = get2(presentBlocksAtom);
1185
1289
  let block = selectedBlock;
1186
1290
  const blocks = [selectedBlock];
1187
1291
  do {
@@ -1207,244 +1311,6 @@ const useSelectedBlockIds = () => {
1207
1311
  );
1208
1312
  return [blockIds, setBlockIds, toggleSelectedBlockId];
1209
1313
  };
1210
- const removeNestedBlocks = (blocks, blockIds) => {
1211
- const _blockIds = [];
1212
- const _blocks = filter(blocks, (block) => {
1213
- if (includes(blockIds, block._id) || includes(blockIds, block._parent)) {
1214
- _blockIds.push(block._id);
1215
- return false;
1216
- }
1217
- return true;
1218
- });
1219
- if (!isEmpty(_blockIds)) return removeNestedBlocks(_blocks, _blockIds);
1220
- return _blocks;
1221
- };
1222
- const useRemoveBlocks = () => {
1223
- const [presentBlocks] = useBlocksStore();
1224
- const [ids2, setSelectedIds] = useSelectedBlockIds();
1225
- const { setNewBlocks } = useBlocksStoreUndoableActions();
1226
- return useCallback(
1227
- (blockIds) => {
1228
- var _a;
1229
- const parentBlockId = ((_a = find(presentBlocks, { _id: blockIds[0] })) == null ? void 0 : _a._parent) || null;
1230
- setNewBlocks(removeNestedBlocks(presentBlocks, blockIds));
1231
- setTimeout(() => setSelectedIds(parentBlockId ? [parentBlockId] : []), 200);
1232
- },
1233
- [presentBlocks, setSelectedIds, ids2]
1234
- );
1235
- };
1236
- const writeAtomValue = atom$1(
1237
- null,
1238
- // it's a convention to pass `null` for the first argument
1239
- (get2, set2, { id, props }) => {
1240
- const blockAsAtoms = get2(pageBlocksAtom);
1241
- console.log("From Atom callback", blockAsAtoms);
1242
- const blockAtom = find(blockAsAtoms, (b) => b._id === id);
1243
- if (!blockAtom) {
1244
- throw new Error(`Block with id ${id} not found`);
1245
- }
1246
- return set2(blockAtom._atom, { ...get2(blockAtom._atom), ...props });
1247
- }
1248
- );
1249
- const useUpdateBlockAtom = () => {
1250
- return useSetAtom$1(writeAtomValue);
1251
- };
1252
- const useGetBlockAtomValue = () => {
1253
- return useAtomCallback(
1254
- useCallback((get2, _set, id) => {
1255
- const blockAsAtoms = get2(pageBlocksAtom);
1256
- console.log("Block As Atoms", blockAsAtoms);
1257
- const blockAtom = find(blockAsAtoms, (b) => b._id === id);
1258
- if (!blockAtom) {
1259
- throw new Error(`Block with id ${id} not found`);
1260
- }
1261
- return get2(blockAtom._atom);
1262
- }, [])
1263
- );
1264
- };
1265
- function insertBlocksAtPosition(allBlocks, newBlocks, parentId, position) {
1266
- let parentBlocks = allBlocks.filter((block) => !block._parent);
1267
- if (parentId) {
1268
- parentBlocks = allBlocks.filter((block) => block._parent === parentId);
1269
- }
1270
- const insertPosition = !isNaN(position) || position > -1 ? Math.min(position, parentBlocks.length) : parentBlocks.length;
1271
- let insertIndex = allBlocks.length;
1272
- for (let i = 0, count = 0; i < allBlocks.length; i++) {
1273
- if (allBlocks[i]._parent === parentId) {
1274
- if (count === insertPosition) {
1275
- insertIndex = i;
1276
- break;
1277
- }
1278
- count++;
1279
- }
1280
- }
1281
- if (!parentId && position !== void 0 && position >= parentBlocks.length) {
1282
- insertIndex = allBlocks.length;
1283
- }
1284
- return [...allBlocks.slice(0, insertIndex), ...newBlocks, ...allBlocks.slice(insertIndex)];
1285
- }
1286
- function getBlocksTree(blocks) {
1287
- return convertToBlocksTree(blocks);
1288
- }
1289
- const nestedToFlatArray = (nestedJson, parent) => flatten(
1290
- nestedJson.map((block) => {
1291
- block = parent ? { ...block, _parent: parent } : { ...block };
1292
- if (block.children) {
1293
- const children = [...block.children];
1294
- delete block.children;
1295
- return flatten([block, ...nestedToFlatArray(children, block._id)]);
1296
- }
1297
- return block;
1298
- })
1299
- );
1300
- function setProjectBlocksInMemory(nodes, initial = false) {
1301
- for (let i = 0; i < nodes.length; i++) {
1302
- const element = nodes[i];
1303
- if (element.global && !initial) {
1304
- nodes[i] = {
1305
- type: "GlobalBlock",
1306
- blockId: element.blockId,
1307
- _parent: get(element, "_parent", null),
1308
- _id: element._id
1309
- };
1310
- } else if (element.children && element.children.length) {
1311
- setProjectBlocksInMemory(element.children);
1312
- }
1313
- }
1314
- }
1315
- function getInnerBlocks(flatArr) {
1316
- let blocks = [];
1317
- let pBlocks = filter(flatArr, { type: "GlobalBlock" });
1318
- if (pBlocks.length > 0) {
1319
- pBlocks = map(pBlocks, getPBlocks);
1320
- each(pBlocks, (pBlock) => {
1321
- blocks = [...blocks, ...getSingleBlock(pBlock)];
1322
- });
1323
- }
1324
- return blocks;
1325
- }
1326
- function getSingleBlock(flatArray) {
1327
- let blocks = [];
1328
- const parent = get(first(flatArray), "_parent", null);
1329
- set(first(flatArray), "_parent", null);
1330
- const block = [flatToNestedInstance.convert(clone(flatArray))];
1331
- setProjectBlocksInMemory(block, true);
1332
- let flat = nestedToFlatArray(block, flatArray[0]._id);
1333
- flat = set(flat, "0._parent", parent);
1334
- blocks = [...blocks, flat, ...getInnerBlocks(flat)];
1335
- return blocks;
1336
- }
1337
- function getPBlocks(block) {
1338
- const rootBlock = find(FLAT_ARRAY, { _id: block._id });
1339
- if (!rootBlock) return [];
1340
- const blocks = [rootBlock];
1341
- const children = filter(FLAT_ARRAY, { _parent: block._id });
1342
- if (children.length) {
1343
- return flatten([...blocks, ...flatten(map(children, getPBlocks))]);
1344
- }
1345
- return flatten(blocks);
1346
- }
1347
- const clone = (obj) => JSON.parse(JSON.stringify(obj));
1348
- let FLAT_ARRAY = [];
1349
- function splitPageBlocks(allPageBlocks) {
1350
- FLAT_ARRAY = allPageBlocks;
1351
- const clonedTree = getBlocksTree(clone(allPageBlocks));
1352
- setProjectBlocksInMemory(clonedTree);
1353
- const pageBlocks = nestedToFlatArray(clonedTree, null);
1354
- const globalBlocks = getInnerBlocks(pageBlocks);
1355
- const mappedBlocks = {};
1356
- each(globalBlocks, (projectBlock) => set(mappedBlocks, first(projectBlock).blockId, projectBlock));
1357
- return [pageBlocks, mappedBlocks];
1358
- }
1359
- function flattenTree(node) {
1360
- let flatArray = [];
1361
- node.walk((n) => {
1362
- delete n.model.children;
1363
- flatArray.push(n.model);
1364
- return true;
1365
- });
1366
- return flatArray;
1367
- }
1368
- function findNodeById(node, id) {
1369
- return node.first((n) => n.model._id === id) || null;
1370
- }
1371
- function moveNode(rootNode, nodeIdToMove, newParentId, position) {
1372
- const nodeToMove = findNodeById(rootNode, nodeIdToMove);
1373
- const newParentNode = findNodeById(rootNode, newParentId);
1374
- if (nodeToMove && newParentNode) {
1375
- nodeToMove.drop();
1376
- if (!newParentNode.children) {
1377
- newParentNode.model.children = [];
1378
- }
1379
- try {
1380
- newParentNode.addChildAtIndex(nodeToMove, position);
1381
- } catch (error) {
1382
- console.error("Error adding child to parent:", error);
1383
- return false;
1384
- }
1385
- return true;
1386
- }
1387
- return false;
1388
- }
1389
- function moveBlocksWithChildren(_blocks, idToMove, newParentId, newPosition, updateBlockAtom) {
1390
- if (!idToMove) return _blocks;
1391
- newParentId = newParentId || "root";
1392
- const tree2 = new TreeModel();
1393
- const root = tree2.parse({ _id: "root", children: getBlocksTree(_blocks) });
1394
- if (moveNode(root, idToMove, newParentId, newPosition)) {
1395
- const newBlocks = flattenTree(root);
1396
- const movedBlock = newBlocks.find((block) => block._id === idToMove);
1397
- if (movedBlock) {
1398
- movedBlock._parent = newParentId === "root" ? null : newParentId;
1399
- updateBlockAtom({ id: movedBlock._id, props: { _parent: movedBlock._parent } });
1400
- }
1401
- newBlocks.shift();
1402
- return convertToBlocksAtoms(newBlocks);
1403
- }
1404
- return _blocks;
1405
- }
1406
- const useBlocksStoreManager = () => {
1407
- const [, setBlocks] = useBlocksStore();
1408
- const { postMessage } = useBroadcastChannel();
1409
- const updateBlockAtom = useUpdateBlockAtom();
1410
- return {
1411
- setNewBlocks: (newBlocks) => {
1412
- setBlocks(newBlocks);
1413
- postMessage({ type: "blocks-updated", blocks: newBlocks });
1414
- },
1415
- addBlocks: (newBlocks, parent, position) => {
1416
- setBlocks((prevBlocks) => {
1417
- const blocks = insertBlocksAtPosition(prevBlocks, newBlocks, parent, position);
1418
- postMessage({ type: "blocks-updated", blocks });
1419
- return blocks;
1420
- });
1421
- },
1422
- removeBlocks: (blockIds) => {
1423
- setBlocks((prevBlocks) => {
1424
- const blocks = removeNestedBlocks(prevBlocks, blockIds);
1425
- postMessage({ type: "blocks-updated", blocks });
1426
- return blocks;
1427
- });
1428
- },
1429
- moveBlocks: (blockIds, newParent, position) => {
1430
- setBlocks((prevBlocks) => {
1431
- let blocks = prevBlocks;
1432
- for (let i = 0; i < blockIds.length; i++) {
1433
- blocks = moveBlocksWithChildren(blocks, blockIds[i], newParent, position, updateBlockAtom);
1434
- }
1435
- postMessage({ type: "blocks-updated", blocks });
1436
- return blocks;
1437
- });
1438
- },
1439
- updateBlocksProps: (blocks) => {
1440
- blocks.forEach((block) => {
1441
- const updatedBlock = omit(block, "_id");
1442
- updateBlockAtom({ id: block._id, props: updatedBlock });
1443
- });
1444
- postMessage({ type: "blocks-props-updated", blocks });
1445
- }
1446
- };
1447
- };
1448
1314
  var undomanager = { exports: {} };
1449
1315
  var hasRequiredUndomanager;
1450
1316
  function requireUndomanager() {
@@ -1598,8 +1464,81 @@ function requireUndomanager() {
1598
1464
  })(undomanager);
1599
1465
  return undomanager.exports;
1600
1466
  }
1601
- var undomanagerExports = requireUndomanager();
1602
- const UndoManager = /* @__PURE__ */ getDefaultExportFromCjs(undomanagerExports);
1467
+ var undomanagerExports = requireUndomanager();
1468
+ const UndoManager = /* @__PURE__ */ getDefaultExportFromCjs(undomanagerExports);
1469
+ function getBlocksTree(blocks) {
1470
+ return convertToBlocksTree(blocks);
1471
+ }
1472
+ const nestedToFlatArray = (nestedJson, parent) => flatten(
1473
+ nestedJson.map((block) => {
1474
+ block = parent ? { ...block, _parent: parent } : { ...block };
1475
+ if (block.children) {
1476
+ const children = [...block.children];
1477
+ delete block.children;
1478
+ return flatten([block, ...nestedToFlatArray(children, block._id)]);
1479
+ }
1480
+ return block;
1481
+ })
1482
+ );
1483
+ function setProjectBlocksInMemory(nodes, initial = false) {
1484
+ for (let i = 0; i < nodes.length; i++) {
1485
+ const element = nodes[i];
1486
+ if (element.global && !initial) {
1487
+ nodes[i] = {
1488
+ type: "GlobalBlock",
1489
+ blockId: element.blockId,
1490
+ _parent: get(element, "_parent", null),
1491
+ _id: element._id
1492
+ };
1493
+ } else if (element.children && element.children.length) {
1494
+ setProjectBlocksInMemory(element.children);
1495
+ }
1496
+ }
1497
+ }
1498
+ function getInnerBlocks(flatArr) {
1499
+ let blocks = [];
1500
+ let pBlocks = filter(flatArr, { type: "GlobalBlock" });
1501
+ if (pBlocks.length > 0) {
1502
+ pBlocks = map(pBlocks, getPBlocks);
1503
+ each(pBlocks, (pBlock) => {
1504
+ blocks = [...blocks, ...getSingleBlock(pBlock)];
1505
+ });
1506
+ }
1507
+ return blocks;
1508
+ }
1509
+ function getSingleBlock(flatArray) {
1510
+ let blocks = [];
1511
+ const parent = get(first(flatArray), "_parent", null);
1512
+ set(first(flatArray), "_parent", null);
1513
+ const block = [flatToNestedInstance.convert(clone(flatArray))];
1514
+ setProjectBlocksInMemory(block, true);
1515
+ let flat = nestedToFlatArray(block, flatArray[0]._id);
1516
+ flat = set(flat, "0._parent", parent);
1517
+ blocks = [...blocks, flat, ...getInnerBlocks(flat)];
1518
+ return blocks;
1519
+ }
1520
+ function getPBlocks(block) {
1521
+ const rootBlock = find(FLAT_ARRAY, { _id: block._id });
1522
+ if (!rootBlock) return [];
1523
+ const blocks = [rootBlock];
1524
+ const children = filter(FLAT_ARRAY, { _parent: block._id });
1525
+ if (children.length) {
1526
+ return flatten([...blocks, ...flatten(map(children, getPBlocks))]);
1527
+ }
1528
+ return flatten(blocks);
1529
+ }
1530
+ const clone = (obj) => JSON.parse(JSON.stringify(obj));
1531
+ let FLAT_ARRAY = [];
1532
+ function splitPageBlocks(allPageBlocks) {
1533
+ FLAT_ARRAY = allPageBlocks;
1534
+ const clonedTree = getBlocksTree(clone(allPageBlocks));
1535
+ setProjectBlocksInMemory(clonedTree);
1536
+ const pageBlocks = nestedToFlatArray(clonedTree, null);
1537
+ const globalBlocks = getInnerBlocks(pageBlocks);
1538
+ const mappedBlocks = {};
1539
+ each(globalBlocks, (projectBlock) => set(mappedBlocks, first(projectBlock).blockId, projectBlock));
1540
+ return [pageBlocks, mappedBlocks];
1541
+ }
1603
1542
  const MODIFIERS = [
1604
1543
  "hover",
1605
1544
  "focus",
@@ -1680,10 +1619,9 @@ const useGetPageData = () => {
1680
1619
  const [projectOptions] = useBrandingOptions();
1681
1620
  const { currentPage } = useCurrentPage();
1682
1621
  const [presentBlocks] = useBlocksStore();
1683
- const getBlockAtomValue = useGetBlockAtomValue();
1684
1622
  return useCallback(() => {
1685
1623
  const blocks = map(presentBlocks, (block) => {
1686
- return omit(getBlockAtomValue(block._id), getBlockBuilderProps(block._type));
1624
+ return omit(block, getBlockBuilderProps(block._type));
1687
1625
  });
1688
1626
  const [pageFilteredBlocks = []] = splitPageBlocks(blocks);
1689
1627
  return {
@@ -1811,8 +1749,232 @@ const useUndoManager = () => {
1811
1749
  clear: undoManager.clear
1812
1750
  };
1813
1751
  };
1752
+ const broadcastChannel = new BroadcastChannel("chaibuilder");
1753
+ const useBroadcastChannel = () => {
1754
+ const pageId = useBuilderProp("pageId", "chaibuilder_page");
1755
+ const postMessage = useDebouncedCallback(
1756
+ (message) => broadcastChannel.postMessage({ ...message, pageId }),
1757
+ [pageId],
1758
+ 200
1759
+ );
1760
+ return { postMessage };
1761
+ };
1762
+ const useUnmountBroadcastChannel = () => {
1763
+ const [, setBlocks] = useBlocksStore();
1764
+ const pageId = useBuilderProp("pageId", "chaibuilder_page");
1765
+ const { updateBlocksProps } = useBlocksStoreManager();
1766
+ useEffect(() => {
1767
+ broadcastChannel.onmessageerror = (event) => {
1768
+ console.log("error", event);
1769
+ };
1770
+ broadcastChannel.onmessage = (event) => {
1771
+ if (event.data.type === "blocks-updated" && event.data.pageId === pageId) {
1772
+ setBlocks(event.data.blocks);
1773
+ }
1774
+ if (event.data.type === "blocks-props-updated" && event.data.pageId === pageId) {
1775
+ updateBlocksProps(event.data.blocks);
1776
+ }
1777
+ };
1778
+ return () => {
1779
+ broadcastChannel.onmessage = null;
1780
+ broadcastChannel.onmessageerror = null;
1781
+ };
1782
+ }, [setBlocks, pageId]);
1783
+ };
1784
+ const removeNestedBlocks = (blocks, blockIds) => {
1785
+ const _blockIds = [];
1786
+ const _blocks = filter(blocks, (block) => {
1787
+ if (includes(blockIds, block._id) || includes(blockIds, block._parent)) {
1788
+ _blockIds.push(block._id);
1789
+ return false;
1790
+ }
1791
+ return true;
1792
+ });
1793
+ if (!isEmpty(_blockIds)) return removeNestedBlocks(_blocks, _blockIds);
1794
+ return _blocks;
1795
+ };
1796
+ const useRemoveBlocks = () => {
1797
+ const [presentBlocks] = useBlocksStore();
1798
+ const [ids2, setSelectedIds] = useSelectedBlockIds();
1799
+ const { setNewBlocks } = useBlocksStoreUndoableActions();
1800
+ return useCallback(
1801
+ (blockIds) => {
1802
+ var _a;
1803
+ const parentBlockId = ((_a = find(presentBlocks, { _id: blockIds[0] })) == null ? void 0 : _a._parent) || null;
1804
+ setNewBlocks(removeNestedBlocks(presentBlocks, blockIds));
1805
+ setTimeout(() => setSelectedIds(parentBlockId ? [parentBlockId] : []), 200);
1806
+ },
1807
+ [presentBlocks, setSelectedIds, ids2]
1808
+ );
1809
+ };
1810
+ const writeAtomValue = atom$1(
1811
+ null,
1812
+ // it's a convention to pass `null` for the first argument
1813
+ (get2, set2, { id, props }) => {
1814
+ const blockAsAtoms = get2(pageBlocksAtomsAtom);
1815
+ const blockAtom = find(blockAsAtoms, (b) => get2(b)._id === id);
1816
+ if (!blockAtom) {
1817
+ throw new Error(`Block with id ${id} not found`);
1818
+ }
1819
+ return set2(blockAtom, { ...get2(blockAtom), ...props });
1820
+ }
1821
+ );
1822
+ const useUpdateBlockAtom = () => {
1823
+ return useSetAtom$1(writeAtomValue);
1824
+ };
1825
+ const useGetBlockAtomValue = (splitAtoms) => {
1826
+ return useAtomCallback(
1827
+ useCallback(
1828
+ (get2, _set, idOrAtom) => {
1829
+ const blockAsAtoms = get2(pageBlocksAtomsAtom);
1830
+ const blockAtom = find(
1831
+ blockAsAtoms,
1832
+ (b) => get2(b)._id === (isString(idOrAtom) ? idOrAtom : get2(idOrAtom)._id)
1833
+ );
1834
+ if (!blockAtom) {
1835
+ console.warn(`Block with id ${idOrAtom} not found`);
1836
+ return;
1837
+ }
1838
+ return get2(blockAtom);
1839
+ },
1840
+ [splitAtoms]
1841
+ )
1842
+ );
1843
+ };
1844
+ const useGetBlockAtom = (splitAtoms) => {
1845
+ return useAtomCallback(
1846
+ useCallback(
1847
+ (get2, _set, idOrAtom) => {
1848
+ const blockAsAtoms = get2(splitAtoms ?? pageBlocksAtomsAtom);
1849
+ const blockAtom = find(
1850
+ blockAsAtoms,
1851
+ (b) => get2(b)._id === (isString(idOrAtom) ? idOrAtom : get2(idOrAtom)._id)
1852
+ );
1853
+ if (!blockAtom) {
1854
+ console.warn(`Block with id ${idOrAtom} not found`);
1855
+ return;
1856
+ }
1857
+ return blockAtom;
1858
+ },
1859
+ [splitAtoms]
1860
+ )
1861
+ );
1862
+ };
1863
+ function insertBlocksAtPosition(allBlocks, newBlocks, parentId, position) {
1864
+ let parentBlocks = allBlocks.filter((block) => !block._parent);
1865
+ if (parentId) {
1866
+ parentBlocks = allBlocks.filter((block) => block._parent === parentId);
1867
+ }
1868
+ const insertPosition = !isNaN(position) || position > -1 ? Math.min(position, parentBlocks.length) : parentBlocks.length;
1869
+ let insertIndex = allBlocks.length;
1870
+ for (let i = 0, count = 0; i < allBlocks.length; i++) {
1871
+ if (allBlocks[i]._parent === parentId) {
1872
+ if (count === insertPosition) {
1873
+ insertIndex = i;
1874
+ break;
1875
+ }
1876
+ count++;
1877
+ }
1878
+ }
1879
+ if (!parentId && position !== void 0 && position >= parentBlocks.length) {
1880
+ insertIndex = allBlocks.length;
1881
+ }
1882
+ return [...allBlocks.slice(0, insertIndex), ...newBlocks, ...allBlocks.slice(insertIndex)];
1883
+ }
1884
+ function flattenTree(node) {
1885
+ let flatArray = [];
1886
+ node.walk((n) => {
1887
+ delete n.model.children;
1888
+ flatArray.push(n.model);
1889
+ return true;
1890
+ });
1891
+ return flatArray;
1892
+ }
1893
+ function findNodeById(node, id) {
1894
+ return node.first((n) => n.model._id === id) || null;
1895
+ }
1896
+ function moveNode(rootNode, nodeIdToMove, newParentId, position) {
1897
+ const nodeToMove = findNodeById(rootNode, nodeIdToMove);
1898
+ const newParentNode = findNodeById(rootNode, newParentId);
1899
+ if (nodeToMove && newParentNode) {
1900
+ nodeToMove.drop();
1901
+ if (!newParentNode.children) {
1902
+ newParentNode.model.children = [];
1903
+ }
1904
+ try {
1905
+ newParentNode.addChildAtIndex(nodeToMove, position);
1906
+ } catch (error) {
1907
+ console.error("Error adding child to parent:", error);
1908
+ return false;
1909
+ }
1910
+ return true;
1911
+ }
1912
+ return false;
1913
+ }
1914
+ function moveBlocksWithChildren(_blocks, idToMove, newParentId, newPosition) {
1915
+ if (!idToMove) return _blocks;
1916
+ newParentId = newParentId || "root";
1917
+ const tree2 = new TreeModel();
1918
+ const root = tree2.parse({ _id: "root", children: getBlocksTree(_blocks) });
1919
+ if (moveNode(root, idToMove, newParentId, newPosition)) {
1920
+ const newBlocks = flattenTree(root);
1921
+ const movedBlock = newBlocks.find((block) => block._id === idToMove);
1922
+ if (movedBlock) movedBlock._parent = newParentId === "root" ? null : newParentId;
1923
+ newBlocks.shift();
1924
+ return newBlocks;
1925
+ }
1926
+ return _blocks;
1927
+ }
1928
+ const useBlocksStoreManager = () => {
1929
+ const [, setBlocks] = useBlocksStore();
1930
+ const { postMessage } = useBroadcastChannel();
1931
+ const updateBlockAtom = useUpdateBlockAtom();
1932
+ return {
1933
+ setNewBlocks: (newBlocks) => {
1934
+ setBlocks(newBlocks);
1935
+ postMessage({ type: "blocks-updated", blocks: newBlocks });
1936
+ },
1937
+ addBlocks: (newBlocks, parent, position) => {
1938
+ setBlocks((prevBlocks) => {
1939
+ const blocks = insertBlocksAtPosition(prevBlocks, newBlocks, parent, position);
1940
+ postMessage({ type: "blocks-updated", blocks });
1941
+ return blocks;
1942
+ });
1943
+ },
1944
+ removeBlocks: (blockIds) => {
1945
+ setBlocks((prevBlocks) => {
1946
+ const blocks = removeNestedBlocks(prevBlocks, blockIds);
1947
+ postMessage({ type: "blocks-updated", blocks });
1948
+ return blocks;
1949
+ });
1950
+ },
1951
+ moveBlocks: (blockIds, newParent, position) => {
1952
+ setBlocks((prevBlocks) => {
1953
+ let blocks = [...prevBlocks];
1954
+ for (let i = 0; i < blockIds.length; i++) {
1955
+ blocks = moveBlocksWithChildren(blocks, blockIds[i], newParent, position);
1956
+ }
1957
+ each(blockIds, (id) => {
1958
+ const block = find(blocks, (b) => b._id === id);
1959
+ if (block) {
1960
+ updateBlockAtom({ id, props: { _parent: block._parent || null } });
1961
+ }
1962
+ });
1963
+ postMessage({ type: "blocks-updated", blocks });
1964
+ return blocks;
1965
+ });
1966
+ },
1967
+ updateBlocksProps: (blocks) => {
1968
+ blocks.forEach((block) => {
1969
+ const updatedBlock = omit(block, "_id");
1970
+ updateBlockAtom({ id: block._id, props: updatedBlock });
1971
+ });
1972
+ postMessage({ type: "blocks-props-updated", blocks });
1973
+ }
1974
+ };
1975
+ };
1814
1976
  const useBlocksStore = () => {
1815
- return useAtom$1(pageBlocksAtom);
1977
+ return useAtom$1(presentBlocksAtom);
1816
1978
  };
1817
1979
  const useBlocksStoreUndoableActions = () => {
1818
1980
  const { add } = useUndoManager();
@@ -1946,7 +2108,7 @@ const useAddBlock = () => {
1946
2108
  blocks[0]._parent = parentBlock._parent;
1947
2109
  parentBlockId = parentBlock._parent;
1948
2110
  }
1949
- addBlocks(convertToBlocksAtoms(blocks), parentBlockId, position);
2111
+ addBlocks(blocks, parentBlockId, position);
1950
2112
  setSelected([(_a = first(blocks)) == null ? void 0 : _a._id]);
1951
2113
  return first(blocks);
1952
2114
  },
@@ -1978,7 +2140,7 @@ const useAddBlock = () => {
1978
2140
  parentBlockId = parentBlock._parent;
1979
2141
  }
1980
2142
  const newBlocks = [newBlock];
1981
- addBlocks(convertToBlocksAtoms(newBlocks), parentBlockId, position);
2143
+ addBlocks(newBlocks, parentBlockId, position);
1982
2144
  setSelected([newBlock._id]);
1983
2145
  return newBlock;
1984
2146
  },
@@ -3176,9 +3338,12 @@ const selectedStylingBlocksAtom = atom$1([]);
3176
3338
  selectedStylingBlocksAtom.debugLabel = "selectedStylingBlocksAtom";
3177
3339
  const useSelectedStylingBlocks = () => useAtom$1(selectedStylingBlocksAtom);
3178
3340
  const addClassesToBlocksAtom = atom$1(null, (get$1, _set, { blockIds, newClasses }) => {
3179
- const blockAtoms = map(
3180
- filter(get$1(pageBlocksAtom), (block) => blockIds.includes(block._id)),
3181
- (block) => block._atom
3341
+ const blockAtoms = filter(
3342
+ get$1(pageBlocksAtomsAtom),
3343
+ (blockAtom) => (
3344
+ // @ts-ignore
3345
+ blockIds.includes(get$1(blockAtom)._id)
3346
+ )
3182
3347
  );
3183
3348
  const styleBlock = first(get$1(selectedStylingBlocksAtom));
3184
3349
  return map(blockAtoms, (blockAtom) => {
@@ -3292,7 +3457,7 @@ const useDuplicateBlocks = () => {
3292
3457
  const blockPosition = siblingBlocks.indexOf(block);
3293
3458
  const newBlockPosition = blockPosition + 1;
3294
3459
  const newBlocks = getDuplicatedBlocks(presentBlocks, blockId, parentId);
3295
- addBlocks(convertToBlocksAtoms(newBlocks), parentId, newBlockPosition);
3460
+ addBlocks(newBlocks, parentId, newBlockPosition);
3296
3461
  newBlockIds.push(get(newBlocks, "0._id", ""));
3297
3462
  });
3298
3463
  setSelected(newBlockIds);
@@ -3326,7 +3491,7 @@ const useCanPaste = () => {
3326
3491
  };
3327
3492
  };
3328
3493
  const useMoveCutBlocks = () => {
3329
- const presentBlocks = useAtomValue$1(pageBlocksAtom);
3494
+ const presentBlocks = useAtomValue$1(presentBlocksAtom);
3330
3495
  const { moveBlocks: moveBlocks2 } = useBlocksStoreUndoableActions();
3331
3496
  return useCallback(
3332
3497
  (blockIds, newParentId) => {
@@ -3404,9 +3569,12 @@ const usePreviewMode = () => {
3404
3569
  };
3405
3570
  const removeClassFromBlocksAtom = atom$1(null, (get$1, _set, { blockIds, fullClasses }) => {
3406
3571
  const styleBlock = first(get$1(selectedStylingBlocksAtom));
3407
- const blockAtoms = map(
3408
- filter(get$1(pageBlocksAtom), (block) => blockIds.includes(block._id)),
3409
- (block) => block._atom
3572
+ const blockAtoms = filter(
3573
+ get$1(pageBlocksAtomsAtom),
3574
+ (blockAtom) => (
3575
+ // @ts-ignore
3576
+ blockIds.includes(get$1(blockAtom)._id)
3577
+ )
3410
3578
  );
3411
3579
  return map(blockAtoms, (blockAtom) => {
3412
3580
  const block = get$1(blockAtom);
@@ -3609,23 +3777,27 @@ const useBlockHighlight = () => {
3609
3777
  var _a;
3610
3778
  return (iframe == null ? void 0 : iframe.contentDocument) || ((_a = iframe == null ? void 0 : iframe.contentWindow) == null ? void 0 : _a.document);
3611
3779
  }, [iframe]);
3612
- const highlightBlock = (elementOrID) => {
3613
- if (lastHighlighted) {
3614
- lastHighlighted.removeAttribute("data-highlighted");
3615
- }
3616
- if (typeof elementOrID !== "string") {
3617
- elementOrID.setAttribute("data-highlighted", "true");
3618
- lastHighlighted = elementOrID;
3619
- } else if (typeof elementOrID === "string") {
3620
- const element = innerDoc.querySelector(`[data-block-id="${elementOrID}"]`);
3621
- if (element) {
3622
- element.setAttribute("data-highlighted", "true");
3623
- lastHighlighted = element;
3780
+ const highlightBlock = useCallback(
3781
+ (elementOrID) => {
3782
+ if (!innerDoc) return;
3783
+ if (lastHighlighted) {
3784
+ lastHighlighted.removeAttribute("data-highlighted");
3785
+ }
3786
+ if (typeof elementOrID !== "string") {
3787
+ elementOrID.setAttribute("data-highlighted", "true");
3788
+ lastHighlighted = elementOrID;
3789
+ } else if (typeof elementOrID === "string") {
3790
+ const element = innerDoc.querySelector(`[data-block-id="${elementOrID}"]`);
3791
+ if (element) {
3792
+ element.setAttribute("data-highlighted", "true");
3793
+ lastHighlighted = element;
3794
+ }
3795
+ } else {
3796
+ lastHighlighted = null;
3624
3797
  }
3625
- } else {
3626
- lastHighlighted = null;
3627
- }
3628
- };
3798
+ },
3799
+ [innerDoc]
3800
+ );
3629
3801
  const clearHighlight = () => {
3630
3802
  if (lastHighlighted) {
3631
3803
  lastHighlighted.removeAttribute("data-highlighted");
@@ -3638,7 +3810,7 @@ const globalBlocksStoreAtom = atom({});
3638
3810
  const globalBlocksLoadingStateAtom = atom({});
3639
3811
  const useGlobalBlocksStore = () => {
3640
3812
  const [globalBlocks, setGlobalBlocks] = useAtom(globalBlocksStoreAtom);
3641
- const getGlobalBlocks = useCallback((globalBlockId) => get(globalBlocks, globalBlockId, []), [globalBlocks]);
3813
+ const getGlobalBlocks = useCallback((globalBlock) => get(globalBlocks, globalBlock, []), [globalBlocks]);
3642
3814
  const reset = useCallback(() => setGlobalBlocks({}), [setGlobalBlocks]);
3643
3815
  return { getGlobalBlocks, reset };
3644
3816
  };
@@ -3646,14 +3818,10 @@ const useWatchGlobalBlocks = () => {
3646
3818
  const [blocksStore] = useBlocksStore();
3647
3819
  const [globalBlocks, setGlobalBlocks] = useAtom(globalBlocksStoreAtom);
3648
3820
  const [globalBlocksLoadingState, setGlobalBlocksLoadingState] = useAtom(globalBlocksLoadingStateAtom);
3649
- const getBlockAtomValue = useGetBlockAtomValue();
3650
3821
  const getGlobalBlockBlocks = useBuilderProp("getGlobalBlockBlocks", async (_key) => []);
3651
3822
  const globalBlocksList = useMemo(() => {
3652
3823
  const globalBlocks2 = blocksStore.filter((block) => block._type === "GlobalBlock");
3653
- return globalBlocks2.filter((block) => block._type === "GlobalBlock").map((block) => {
3654
- const blockValue = getBlockAtomValue(block._id);
3655
- return blockValue.globalBlock;
3656
- });
3824
+ return globalBlocks2.filter((block) => block._type === "GlobalBlock").map((block) => block.globalBlock);
3657
3825
  }, [blocksStore]);
3658
3826
  useEffect(() => {
3659
3827
  forEach(globalBlocksList, (globalBlock) => {
@@ -4055,7 +4223,7 @@ const useAiAssistant = () => {
4055
4223
  };
4056
4224
  const wrapperBlockAtom = atom$1((get2) => {
4057
4225
  var _a;
4058
- const blocks = get2(pageBlocksAtom);
4226
+ const blocks = get2(presentBlocksAtom);
4059
4227
  const blockIds = get2(selectedBlockIdsAtom);
4060
4228
  const blockId = blockIds.length === 1 ? blockIds[0] : null;
4061
4229
  if (!blockId) return null;
@@ -4889,7 +5057,7 @@ const BlockRenderer = ({ blockAtom, children }) => {
4889
5057
  const blockAttributesProps = useMemo(() => getBlockTagAttributes(block), [block]);
4890
5058
  const runtimeProps = useMemo(() => getRuntimePropValues(block._id, getBlockRuntimeProps(block._type)), [block]);
4891
5059
  const dataProviderProps = useMemo(() => {
4892
- if (!has(registeredChaiBlock, "dataProvider") || !isFunction(registeredChaiBlock.dataProvider)) return {};
5060
+ if (!has(registeredChaiBlock, "dataProvider") || !isFunction$1(registeredChaiBlock.dataProvider)) return {};
4893
5061
  return registeredChaiBlock.dataProvider(block, selectedLang);
4894
5062
  }, [block, selectedLang, registeredChaiBlock]);
4895
5063
  const props = useMemo(
@@ -4913,23 +5081,28 @@ const BlockRenderer = ({ blockAtom, children }) => {
4913
5081
  const GlobalBlocksRenderer = ({ blockAtom }) => {
4914
5082
  const { getGlobalBlocks } = useGlobalBlocksStore();
4915
5083
  const [block] = useAtom$1(blockAtom);
4916
- const globalBlocks = useMemo(() => getGlobalBlocks(block == null ? void 0 : block.globalBlock), [block == null ? void 0 : block.globalBlock, getGlobalBlocks]);
4917
- const globalBlocksAtoms = useMemo(() => convertToBlocksAtoms(globalBlocks), [globalBlocks]);
4918
- return /* @__PURE__ */ jsx(BlocksRenderer, { blocks: globalBlocksAtoms, filterFn: (block2) => isEmpty(block2._parent) });
5084
+ const globalBlocks = useMemo(() => getGlobalBlocks((block == null ? void 0 : block.globalBlock) ?? ""), [getGlobalBlocks, block == null ? void 0 : block.globalBlock]);
5085
+ const blocksAtoms = useMemo(() => splitAtom(atom$1(globalBlocks)), [globalBlocks]);
5086
+ return /* @__PURE__ */ jsx(BlocksRenderer, { splitAtoms: blocksAtoms, blocks: globalBlocks });
4919
5087
  };
4920
5088
  const BlocksRenderer = ({
4921
5089
  blocks,
4922
- filterFn
5090
+ parent = null,
5091
+ splitAtoms = void 0
4923
5092
  }) => {
4924
- const filteredBlocks = useMemo(() => filter(blocks, filterFn), [blocks, filterFn]);
4925
- const hasChildren = (blockId) => filter(blocks, (b) => b._parent === blockId).length > 0;
5093
+ const getAtomValue = useGetBlockAtom(splitAtoms);
5094
+ const filteredBlocks = useMemo(
5095
+ () => filter(blocks, (block) => isString(parent) ? block._parent === parent : !block._parent),
5096
+ [blocks, parent]
5097
+ );
5098
+ const hasChildren = useCallback((block) => filter(blocks, (b) => b._parent === block._id).length > 0, [blocks]);
4926
5099
  return map(filteredBlocks, (block) => {
4927
- return /* @__PURE__ */ jsx(BlockRenderer, { blockAtom: block._atom, children: block._type === "GlobalBlock" ? /* @__PURE__ */ jsx(GlobalBlocksRenderer, { blockAtom: block._atom }) : hasChildren(block._id) ? /* @__PURE__ */ jsx(BlocksRenderer, { blocks, filterFn: (b) => b._parent === block._id }) : null }, block._id);
5100
+ return /* @__PURE__ */ jsx(BlockRenderer, { blockAtom: getAtomValue(block._id), children: block._type === "GlobalBlock" ? /* @__PURE__ */ jsx(GlobalBlocksRenderer, { blockAtom: getAtomValue(block._id) }) : hasChildren(block) ? /* @__PURE__ */ jsx(BlocksRenderer, { splitAtoms, blocks, parent: block._id }) : null }, block._id);
4928
5101
  });
4929
5102
  };
4930
5103
  const PageBlocksRenderer = () => {
4931
5104
  const [blocks] = useBlocksStore();
4932
- return /* @__PURE__ */ jsx(BlocksRenderer, { blocks, filterFn: (block) => isEmpty(block._parent) });
5105
+ return /* @__PURE__ */ jsx(BlocksRenderer, { blocks });
4933
5106
  };
4934
5107
  const StaticBlocksRenderer = () => {
4935
5108
  const [blocks] = useBlocksStore();
@@ -6141,7 +6314,7 @@ const JSONForm = memo(({ blockId, schema, uiSchema, formData, onChange }) => {
6141
6314
  onChange({ formData: formData2 }, id);
6142
6315
  },
6143
6316
  [onChange, selectedLang],
6144
- 400
6317
+ 1e3
6145
6318
  // save only every 5 seconds
6146
6319
  );
6147
6320
  return /* @__PURE__ */ jsx(
@@ -8383,7 +8556,7 @@ const CoreBlock = ({
8383
8556
  const { clearHighlight } = useBlockHighlight();
8384
8557
  const addBlockToPage = () => {
8385
8558
  if (has(block, "blocks")) {
8386
- const blocks = isFunction(block.blocks) ? block.blocks() : block.blocks;
8559
+ const blocks = isFunction$1(block.blocks) ? block.blocks() : block.blocks;
8387
8560
  addPredefinedBlock(syncBlocksWithDefaults(blocks), parentId || null, position);
8388
8561
  } else {
8389
8562
  addCoreBlock(block, parentId || null, position);
@@ -10867,7 +11040,7 @@ const getParentNodeIds = (blocks, id) => {
10867
11040
  const expandedIdsAtom = atom$1([]);
10868
11041
  const useExpandTree = () => {
10869
11042
  const [ids2] = useSelectedBlockIds();
10870
- const pageBlocks = useAtomValue$1(pageBlocksAtom);
11043
+ const pageBlocks = useAtomValue$1(presentBlocksAtom);
10871
11044
  const [, setExpandedIds] = useAtom$1(expandedIdsAtom);
10872
11045
  useEffect(() => {
10873
11046
  let expandedIds = [];
@@ -11508,7 +11681,7 @@ const ChaiBuilderComponent = (props) => {
11508
11681
  useEffect(() => {
11509
11682
  setTimeout(() => {
11510
11683
  const withDefaults = syncBlocksWithDefaults(props.blocks || []);
11511
- setAllBlocks(convertToBlocksAtoms(withDefaults));
11684
+ setAllBlocks(withDefaults);
11512
11685
  if (withDefaults && withDefaults.length > 0) {
11513
11686
  postMessage({ type: "blocks-updated", blocks: withDefaults });
11514
11687
  }