@chaibuilder/sdk 2.0.0-beta.90 → 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,247 +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 useUpdateBlockAtom = () => {
1237
- const [blocks] = useBlocksStore();
1238
- console.log("Default Blocks: ", blocks);
1239
- return useAtomCallback(
1240
- useCallback(
1241
- (get2, set2, { id, props }) => {
1242
- const blockAsAtoms = get2(pageBlocksAtom);
1243
- console.log("From Atom callback", blocks);
1244
- const blockAtom = find(blockAsAtoms, (b) => b._id === id);
1245
- if (!blockAtom) {
1246
- console.warn(`Block with id ${id} not found`);
1247
- return;
1248
- }
1249
- return set2(blockAtom._atom, { ...get2(blockAtom._atom), ...props });
1250
- },
1251
- [pageBlocksAtom]
1252
- )
1253
- );
1254
- };
1255
- const useGetBlockAtomValue = () => {
1256
- return useAtomCallback(
1257
- useCallback((get2, _set, id) => {
1258
- const blockAsAtoms = get2(pageBlocksAtom);
1259
- const blockAtom = find(blockAsAtoms, (b) => b._id === id);
1260
- if (!blockAtom) {
1261
- console.warn(`Block with id ${id} not found`);
1262
- return;
1263
- }
1264
- return get2(blockAtom._atom);
1265
- }, [])
1266
- );
1267
- };
1268
- function insertBlocksAtPosition(allBlocks, newBlocks, parentId, position) {
1269
- let parentBlocks = allBlocks.filter((block) => !block._parent);
1270
- if (parentId) {
1271
- parentBlocks = allBlocks.filter((block) => block._parent === parentId);
1272
- }
1273
- const insertPosition = !isNaN(position) || position > -1 ? Math.min(position, parentBlocks.length) : parentBlocks.length;
1274
- let insertIndex = allBlocks.length;
1275
- for (let i = 0, count = 0; i < allBlocks.length; i++) {
1276
- if (allBlocks[i]._parent === parentId) {
1277
- if (count === insertPosition) {
1278
- insertIndex = i;
1279
- break;
1280
- }
1281
- count++;
1282
- }
1283
- }
1284
- if (!parentId && position !== void 0 && position >= parentBlocks.length) {
1285
- insertIndex = allBlocks.length;
1286
- }
1287
- return [...allBlocks.slice(0, insertIndex), ...newBlocks, ...allBlocks.slice(insertIndex)];
1288
- }
1289
- function getBlocksTree(blocks) {
1290
- return convertToBlocksTree(blocks);
1291
- }
1292
- const nestedToFlatArray = (nestedJson, parent) => flatten(
1293
- nestedJson.map((block) => {
1294
- block = parent ? { ...block, _parent: parent } : { ...block };
1295
- if (block.children) {
1296
- const children = [...block.children];
1297
- delete block.children;
1298
- return flatten([block, ...nestedToFlatArray(children, block._id)]);
1299
- }
1300
- return block;
1301
- })
1302
- );
1303
- function setProjectBlocksInMemory(nodes, initial = false) {
1304
- for (let i = 0; i < nodes.length; i++) {
1305
- const element = nodes[i];
1306
- if (element.global && !initial) {
1307
- nodes[i] = {
1308
- type: "GlobalBlock",
1309
- blockId: element.blockId,
1310
- _parent: get(element, "_parent", null),
1311
- _id: element._id
1312
- };
1313
- } else if (element.children && element.children.length) {
1314
- setProjectBlocksInMemory(element.children);
1315
- }
1316
- }
1317
- }
1318
- function getInnerBlocks(flatArr) {
1319
- let blocks = [];
1320
- let pBlocks = filter(flatArr, { type: "GlobalBlock" });
1321
- if (pBlocks.length > 0) {
1322
- pBlocks = map(pBlocks, getPBlocks);
1323
- each(pBlocks, (pBlock) => {
1324
- blocks = [...blocks, ...getSingleBlock(pBlock)];
1325
- });
1326
- }
1327
- return blocks;
1328
- }
1329
- function getSingleBlock(flatArray) {
1330
- let blocks = [];
1331
- const parent = get(first(flatArray), "_parent", null);
1332
- set(first(flatArray), "_parent", null);
1333
- const block = [flatToNestedInstance.convert(clone(flatArray))];
1334
- setProjectBlocksInMemory(block, true);
1335
- let flat = nestedToFlatArray(block, flatArray[0]._id);
1336
- flat = set(flat, "0._parent", parent);
1337
- blocks = [...blocks, flat, ...getInnerBlocks(flat)];
1338
- return blocks;
1339
- }
1340
- function getPBlocks(block) {
1341
- const rootBlock = find(FLAT_ARRAY, { _id: block._id });
1342
- if (!rootBlock) return [];
1343
- const blocks = [rootBlock];
1344
- const children = filter(FLAT_ARRAY, { _parent: block._id });
1345
- if (children.length) {
1346
- return flatten([...blocks, ...flatten(map(children, getPBlocks))]);
1347
- }
1348
- return flatten(blocks);
1349
- }
1350
- const clone = (obj) => JSON.parse(JSON.stringify(obj));
1351
- let FLAT_ARRAY = [];
1352
- function splitPageBlocks(allPageBlocks) {
1353
- FLAT_ARRAY = allPageBlocks;
1354
- const clonedTree = getBlocksTree(clone(allPageBlocks));
1355
- setProjectBlocksInMemory(clonedTree);
1356
- const pageBlocks = nestedToFlatArray(clonedTree, null);
1357
- const globalBlocks = getInnerBlocks(pageBlocks);
1358
- const mappedBlocks = {};
1359
- each(globalBlocks, (projectBlock) => set(mappedBlocks, first(projectBlock).blockId, projectBlock));
1360
- return [pageBlocks, mappedBlocks];
1361
- }
1362
- function flattenTree(node) {
1363
- let flatArray = [];
1364
- node.walk((n) => {
1365
- delete n.model.children;
1366
- flatArray.push(n.model);
1367
- return true;
1368
- });
1369
- return flatArray;
1370
- }
1371
- function findNodeById(node, id) {
1372
- return node.first((n) => n.model._id === id) || null;
1373
- }
1374
- function moveNode(rootNode, nodeIdToMove, newParentId, position) {
1375
- const nodeToMove = findNodeById(rootNode, nodeIdToMove);
1376
- const newParentNode = findNodeById(rootNode, newParentId);
1377
- if (nodeToMove && newParentNode) {
1378
- nodeToMove.drop();
1379
- if (!newParentNode.children) {
1380
- newParentNode.model.children = [];
1381
- }
1382
- try {
1383
- newParentNode.addChildAtIndex(nodeToMove, position);
1384
- } catch (error) {
1385
- console.error("Error adding child to parent:", error);
1386
- return false;
1387
- }
1388
- return true;
1389
- }
1390
- return false;
1391
- }
1392
- function moveBlocksWithChildren(_blocks, idToMove, newParentId, newPosition, updateBlockAtom) {
1393
- if (!idToMove) return _blocks;
1394
- newParentId = newParentId || "root";
1395
- const tree2 = new TreeModel();
1396
- const root = tree2.parse({ _id: "root", children: getBlocksTree(_blocks) });
1397
- if (moveNode(root, idToMove, newParentId, newPosition)) {
1398
- const newBlocks = flattenTree(root);
1399
- const movedBlock = newBlocks.find((block) => block._id === idToMove);
1400
- if (movedBlock) {
1401
- movedBlock._parent = newParentId === "root" ? null : newParentId;
1402
- updateBlockAtom({ id: movedBlock._id, props: { _parent: movedBlock._parent } });
1403
- }
1404
- newBlocks.shift();
1405
- return convertToBlocksAtoms(newBlocks);
1406
- }
1407
- return _blocks;
1408
- }
1409
- const useBlocksStoreManager = () => {
1410
- const [, setBlocks] = useBlocksStore();
1411
- const { postMessage } = useBroadcastChannel();
1412
- const updateBlockAtom = useUpdateBlockAtom();
1413
- return {
1414
- setNewBlocks: (newBlocks) => {
1415
- setBlocks(newBlocks);
1416
- postMessage({ type: "blocks-updated", blocks: newBlocks });
1417
- },
1418
- addBlocks: (newBlocks, parent, position) => {
1419
- setBlocks((prevBlocks) => {
1420
- const blocks = insertBlocksAtPosition(prevBlocks, newBlocks, parent, position);
1421
- postMessage({ type: "blocks-updated", blocks });
1422
- return blocks;
1423
- });
1424
- },
1425
- removeBlocks: (blockIds) => {
1426
- setBlocks((prevBlocks) => {
1427
- const blocks = removeNestedBlocks(prevBlocks, blockIds);
1428
- postMessage({ type: "blocks-updated", blocks });
1429
- return blocks;
1430
- });
1431
- },
1432
- moveBlocks: (blockIds, newParent, position) => {
1433
- setBlocks((prevBlocks) => {
1434
- let blocks = prevBlocks;
1435
- for (let i = 0; i < blockIds.length; i++) {
1436
- blocks = moveBlocksWithChildren(blocks, blockIds[i], newParent, position, updateBlockAtom);
1437
- }
1438
- postMessage({ type: "blocks-updated", blocks });
1439
- return blocks;
1440
- });
1441
- },
1442
- updateBlocksProps: (blocks) => {
1443
- blocks.forEach((block) => {
1444
- const updatedBlock = omit(block, "_id");
1445
- updateBlockAtom({ id: block._id, props: updatedBlock });
1446
- });
1447
- postMessage({ type: "blocks-props-updated", blocks });
1448
- }
1449
- };
1450
- };
1451
1314
  var undomanager = { exports: {} };
1452
1315
  var hasRequiredUndomanager;
1453
1316
  function requireUndomanager() {
@@ -1601,8 +1464,81 @@ function requireUndomanager() {
1601
1464
  })(undomanager);
1602
1465
  return undomanager.exports;
1603
1466
  }
1604
- var undomanagerExports = requireUndomanager();
1605
- 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
+ }
1606
1542
  const MODIFIERS = [
1607
1543
  "hover",
1608
1544
  "focus",
@@ -1683,10 +1619,9 @@ const useGetPageData = () => {
1683
1619
  const [projectOptions] = useBrandingOptions();
1684
1620
  const { currentPage } = useCurrentPage();
1685
1621
  const [presentBlocks] = useBlocksStore();
1686
- const getBlockAtomValue = useGetBlockAtomValue();
1687
1622
  return useCallback(() => {
1688
1623
  const blocks = map(presentBlocks, (block) => {
1689
- return omit(getBlockAtomValue(block._id), getBlockBuilderProps(block._type));
1624
+ return omit(block, getBlockBuilderProps(block._type));
1690
1625
  });
1691
1626
  const [pageFilteredBlocks = []] = splitPageBlocks(blocks);
1692
1627
  return {
@@ -1814,8 +1749,232 @@ const useUndoManager = () => {
1814
1749
  clear: undoManager.clear
1815
1750
  };
1816
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
+ };
1817
1976
  const useBlocksStore = () => {
1818
- return useAtom$1(pageBlocksAtom);
1977
+ return useAtom$1(presentBlocksAtom);
1819
1978
  };
1820
1979
  const useBlocksStoreUndoableActions = () => {
1821
1980
  const { add } = useUndoManager();
@@ -1949,7 +2108,7 @@ const useAddBlock = () => {
1949
2108
  blocks[0]._parent = parentBlock._parent;
1950
2109
  parentBlockId = parentBlock._parent;
1951
2110
  }
1952
- addBlocks(convertToBlocksAtoms(blocks), parentBlockId, position);
2111
+ addBlocks(blocks, parentBlockId, position);
1953
2112
  setSelected([(_a = first(blocks)) == null ? void 0 : _a._id]);
1954
2113
  return first(blocks);
1955
2114
  },
@@ -1981,7 +2140,7 @@ const useAddBlock = () => {
1981
2140
  parentBlockId = parentBlock._parent;
1982
2141
  }
1983
2142
  const newBlocks = [newBlock];
1984
- addBlocks(convertToBlocksAtoms(newBlocks), parentBlockId, position);
2143
+ addBlocks(newBlocks, parentBlockId, position);
1985
2144
  setSelected([newBlock._id]);
1986
2145
  return newBlock;
1987
2146
  },
@@ -3179,9 +3338,12 @@ const selectedStylingBlocksAtom = atom$1([]);
3179
3338
  selectedStylingBlocksAtom.debugLabel = "selectedStylingBlocksAtom";
3180
3339
  const useSelectedStylingBlocks = () => useAtom$1(selectedStylingBlocksAtom);
3181
3340
  const addClassesToBlocksAtom = atom$1(null, (get$1, _set, { blockIds, newClasses }) => {
3182
- const blockAtoms = map(
3183
- filter(get$1(pageBlocksAtom), (block) => blockIds.includes(block._id)),
3184
- (block) => block._atom
3341
+ const blockAtoms = filter(
3342
+ get$1(pageBlocksAtomsAtom),
3343
+ (blockAtom) => (
3344
+ // @ts-ignore
3345
+ blockIds.includes(get$1(blockAtom)._id)
3346
+ )
3185
3347
  );
3186
3348
  const styleBlock = first(get$1(selectedStylingBlocksAtom));
3187
3349
  return map(blockAtoms, (blockAtom) => {
@@ -3295,7 +3457,7 @@ const useDuplicateBlocks = () => {
3295
3457
  const blockPosition = siblingBlocks.indexOf(block);
3296
3458
  const newBlockPosition = blockPosition + 1;
3297
3459
  const newBlocks = getDuplicatedBlocks(presentBlocks, blockId, parentId);
3298
- addBlocks(convertToBlocksAtoms(newBlocks), parentId, newBlockPosition);
3460
+ addBlocks(newBlocks, parentId, newBlockPosition);
3299
3461
  newBlockIds.push(get(newBlocks, "0._id", ""));
3300
3462
  });
3301
3463
  setSelected(newBlockIds);
@@ -3329,7 +3491,7 @@ const useCanPaste = () => {
3329
3491
  };
3330
3492
  };
3331
3493
  const useMoveCutBlocks = () => {
3332
- const presentBlocks = useAtomValue$1(pageBlocksAtom);
3494
+ const presentBlocks = useAtomValue$1(presentBlocksAtom);
3333
3495
  const { moveBlocks: moveBlocks2 } = useBlocksStoreUndoableActions();
3334
3496
  return useCallback(
3335
3497
  (blockIds, newParentId) => {
@@ -3407,9 +3569,12 @@ const usePreviewMode = () => {
3407
3569
  };
3408
3570
  const removeClassFromBlocksAtom = atom$1(null, (get$1, _set, { blockIds, fullClasses }) => {
3409
3571
  const styleBlock = first(get$1(selectedStylingBlocksAtom));
3410
- const blockAtoms = map(
3411
- filter(get$1(pageBlocksAtom), (block) => blockIds.includes(block._id)),
3412
- (block) => block._atom
3572
+ const blockAtoms = filter(
3573
+ get$1(pageBlocksAtomsAtom),
3574
+ (blockAtom) => (
3575
+ // @ts-ignore
3576
+ blockIds.includes(get$1(blockAtom)._id)
3577
+ )
3413
3578
  );
3414
3579
  return map(blockAtoms, (blockAtom) => {
3415
3580
  const block = get$1(blockAtom);
@@ -3612,23 +3777,27 @@ const useBlockHighlight = () => {
3612
3777
  var _a;
3613
3778
  return (iframe == null ? void 0 : iframe.contentDocument) || ((_a = iframe == null ? void 0 : iframe.contentWindow) == null ? void 0 : _a.document);
3614
3779
  }, [iframe]);
3615
- const highlightBlock = (elementOrID) => {
3616
- if (lastHighlighted) {
3617
- lastHighlighted.removeAttribute("data-highlighted");
3618
- }
3619
- if (typeof elementOrID !== "string") {
3620
- elementOrID.setAttribute("data-highlighted", "true");
3621
- lastHighlighted = elementOrID;
3622
- } else if (typeof elementOrID === "string") {
3623
- const element = innerDoc.querySelector(`[data-block-id="${elementOrID}"]`);
3624
- if (element) {
3625
- element.setAttribute("data-highlighted", "true");
3626
- 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;
3627
3797
  }
3628
- } else {
3629
- lastHighlighted = null;
3630
- }
3631
- };
3798
+ },
3799
+ [innerDoc]
3800
+ );
3632
3801
  const clearHighlight = () => {
3633
3802
  if (lastHighlighted) {
3634
3803
  lastHighlighted.removeAttribute("data-highlighted");
@@ -3641,7 +3810,7 @@ const globalBlocksStoreAtom = atom({});
3641
3810
  const globalBlocksLoadingStateAtom = atom({});
3642
3811
  const useGlobalBlocksStore = () => {
3643
3812
  const [globalBlocks, setGlobalBlocks] = useAtom(globalBlocksStoreAtom);
3644
- const getGlobalBlocks = useCallback((globalBlockId) => get(globalBlocks, globalBlockId, []), [globalBlocks]);
3813
+ const getGlobalBlocks = useCallback((globalBlock) => get(globalBlocks, globalBlock, []), [globalBlocks]);
3645
3814
  const reset = useCallback(() => setGlobalBlocks({}), [setGlobalBlocks]);
3646
3815
  return { getGlobalBlocks, reset };
3647
3816
  };
@@ -3649,14 +3818,10 @@ const useWatchGlobalBlocks = () => {
3649
3818
  const [blocksStore] = useBlocksStore();
3650
3819
  const [globalBlocks, setGlobalBlocks] = useAtom(globalBlocksStoreAtom);
3651
3820
  const [globalBlocksLoadingState, setGlobalBlocksLoadingState] = useAtom(globalBlocksLoadingStateAtom);
3652
- const getBlockAtomValue = useGetBlockAtomValue();
3653
3821
  const getGlobalBlockBlocks = useBuilderProp("getGlobalBlockBlocks", async (_key) => []);
3654
3822
  const globalBlocksList = useMemo(() => {
3655
3823
  const globalBlocks2 = blocksStore.filter((block) => block._type === "GlobalBlock");
3656
- return globalBlocks2.filter((block) => block._type === "GlobalBlock").map((block) => {
3657
- const blockValue = getBlockAtomValue(block._id);
3658
- return blockValue.globalBlock;
3659
- });
3824
+ return globalBlocks2.filter((block) => block._type === "GlobalBlock").map((block) => block.globalBlock);
3660
3825
  }, [blocksStore]);
3661
3826
  useEffect(() => {
3662
3827
  forEach(globalBlocksList, (globalBlock) => {
@@ -4058,7 +4223,7 @@ const useAiAssistant = () => {
4058
4223
  };
4059
4224
  const wrapperBlockAtom = atom$1((get2) => {
4060
4225
  var _a;
4061
- const blocks = get2(pageBlocksAtom);
4226
+ const blocks = get2(presentBlocksAtom);
4062
4227
  const blockIds = get2(selectedBlockIdsAtom);
4063
4228
  const blockId = blockIds.length === 1 ? blockIds[0] : null;
4064
4229
  if (!blockId) return null;
@@ -4892,7 +5057,7 @@ const BlockRenderer = ({ blockAtom, children }) => {
4892
5057
  const blockAttributesProps = useMemo(() => getBlockTagAttributes(block), [block]);
4893
5058
  const runtimeProps = useMemo(() => getRuntimePropValues(block._id, getBlockRuntimeProps(block._type)), [block]);
4894
5059
  const dataProviderProps = useMemo(() => {
4895
- if (!has(registeredChaiBlock, "dataProvider") || !isFunction(registeredChaiBlock.dataProvider)) return {};
5060
+ if (!has(registeredChaiBlock, "dataProvider") || !isFunction$1(registeredChaiBlock.dataProvider)) return {};
4896
5061
  return registeredChaiBlock.dataProvider(block, selectedLang);
4897
5062
  }, [block, selectedLang, registeredChaiBlock]);
4898
5063
  const props = useMemo(
@@ -4916,23 +5081,28 @@ const BlockRenderer = ({ blockAtom, children }) => {
4916
5081
  const GlobalBlocksRenderer = ({ blockAtom }) => {
4917
5082
  const { getGlobalBlocks } = useGlobalBlocksStore();
4918
5083
  const [block] = useAtom$1(blockAtom);
4919
- const globalBlocks = useMemo(() => getGlobalBlocks(block == null ? void 0 : block.globalBlock), [block == null ? void 0 : block.globalBlock, getGlobalBlocks]);
4920
- const globalBlocksAtoms = useMemo(() => convertToBlocksAtoms(globalBlocks), [globalBlocks]);
4921
- 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 });
4922
5087
  };
4923
5088
  const BlocksRenderer = ({
4924
5089
  blocks,
4925
- filterFn
5090
+ parent = null,
5091
+ splitAtoms = void 0
4926
5092
  }) => {
4927
- const filteredBlocks = useMemo(() => filter(blocks, filterFn), [blocks, filterFn]);
4928
- 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]);
4929
5099
  return map(filteredBlocks, (block) => {
4930
- 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);
4931
5101
  });
4932
5102
  };
4933
5103
  const PageBlocksRenderer = () => {
4934
5104
  const [blocks] = useBlocksStore();
4935
- return /* @__PURE__ */ jsx(BlocksRenderer, { blocks, filterFn: (block) => isEmpty(block._parent) });
5105
+ return /* @__PURE__ */ jsx(BlocksRenderer, { blocks });
4936
5106
  };
4937
5107
  const StaticBlocksRenderer = () => {
4938
5108
  const [blocks] = useBlocksStore();
@@ -6144,7 +6314,7 @@ const JSONForm = memo(({ blockId, schema, uiSchema, formData, onChange }) => {
6144
6314
  onChange({ formData: formData2 }, id);
6145
6315
  },
6146
6316
  [onChange, selectedLang],
6147
- 400
6317
+ 1e3
6148
6318
  // save only every 5 seconds
6149
6319
  );
6150
6320
  return /* @__PURE__ */ jsx(
@@ -8386,7 +8556,7 @@ const CoreBlock = ({
8386
8556
  const { clearHighlight } = useBlockHighlight();
8387
8557
  const addBlockToPage = () => {
8388
8558
  if (has(block, "blocks")) {
8389
- const blocks = isFunction(block.blocks) ? block.blocks() : block.blocks;
8559
+ const blocks = isFunction$1(block.blocks) ? block.blocks() : block.blocks;
8390
8560
  addPredefinedBlock(syncBlocksWithDefaults(blocks), parentId || null, position);
8391
8561
  } else {
8392
8562
  addCoreBlock(block, parentId || null, position);
@@ -10870,7 +11040,7 @@ const getParentNodeIds = (blocks, id) => {
10870
11040
  const expandedIdsAtom = atom$1([]);
10871
11041
  const useExpandTree = () => {
10872
11042
  const [ids2] = useSelectedBlockIds();
10873
- const pageBlocks = useAtomValue$1(pageBlocksAtom);
11043
+ const pageBlocks = useAtomValue$1(presentBlocksAtom);
10874
11044
  const [, setExpandedIds] = useAtom$1(expandedIdsAtom);
10875
11045
  useEffect(() => {
10876
11046
  let expandedIds = [];
@@ -11511,7 +11681,7 @@ const ChaiBuilderComponent = (props) => {
11511
11681
  useEffect(() => {
11512
11682
  setTimeout(() => {
11513
11683
  const withDefaults = syncBlocksWithDefaults(props.blocks || []);
11514
- setAllBlocks(convertToBlocksAtoms(withDefaults));
11684
+ setAllBlocks(withDefaults);
11515
11685
  if (withDefaults && withDefaults.length > 0) {
11516
11686
  postMessage({ type: "blocks-updated", blocks: withDefaults });
11517
11687
  }