@netlisian/softconfig 0.0.0-alpha-20251026130436

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.
@@ -0,0 +1,2792 @@
1
+ 'use client'
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
20
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
+ var __objRest = (source, exclude) => {
22
+ var target = {};
23
+ for (var prop in source)
24
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
25
+ target[prop] = source[prop];
26
+ if (source != null && __getOwnPropSymbols)
27
+ for (var prop of __getOwnPropSymbols(source)) {
28
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
29
+ target[prop] = source[prop];
30
+ }
31
+ return target;
32
+ };
33
+ var __async = (__this, __arguments, generator) => {
34
+ return new Promise((resolve, reject) => {
35
+ var fulfilled = (value) => {
36
+ try {
37
+ step(generator.next(value));
38
+ } catch (e) {
39
+ reject(e);
40
+ }
41
+ };
42
+ var rejected = (value) => {
43
+ try {
44
+ step(generator.throw(value));
45
+ } catch (e) {
46
+ reject(e);
47
+ }
48
+ };
49
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
50
+ step((generator = generator.apply(__this, __arguments)).next());
51
+ });
52
+ };
53
+
54
+ // src/puck/store/index.tsx
55
+ import { create } from "zustand";
56
+ import { subscribeWithSelector, devtools } from "zustand/middleware";
57
+
58
+ // src/puck/lib/get-root-props.ts
59
+ var getRootProps = (appState) => appState.data.root.props;
60
+
61
+ // src/puck/lib/builder/root-config.tsx
62
+ import {
63
+ createUsePuck,
64
+ walkTree
65
+ } from "@measured/puck";
66
+
67
+ // src/puck/lib/get-field-settings.tsx
68
+ import { AutoField } from "@measured/puck";
69
+ import { jsx } from "react/jsx-runtime";
70
+ var getFieldSettings = (_fields, _fieldSettings, deep) => {
71
+ return (_fields || []).reduce((fields, field) => {
72
+ const fieldSettings = {
73
+ // placeholder: { type: "text", label: "Placeholder" },
74
+ };
75
+ const currentFieldSettings = _fieldSettings == null ? void 0 : _fieldSettings[field.name];
76
+ switch (field.type) {
77
+ case "text":
78
+ case "textarea":
79
+ fieldSettings.defaultValue = {
80
+ type: field.type,
81
+ label: "Default Value"
82
+ };
83
+ break;
84
+ case "number":
85
+ fieldSettings.defaultValue = {
86
+ type: field.type,
87
+ label: "Default Value"
88
+ };
89
+ fieldSettings.min = {
90
+ type: field.type,
91
+ label: "Minimum Value"
92
+ };
93
+ fieldSettings.max = {
94
+ type: field.type,
95
+ label: "Maximum Value"
96
+ };
97
+ fieldSettings.step = {
98
+ type: field.type,
99
+ label: "Step Size"
100
+ };
101
+ break;
102
+ case "radio":
103
+ case "select":
104
+ fieldSettings.defaultValue = {
105
+ type: "custom",
106
+ label: "Default Value",
107
+ render: ({ value, onChange, id }) => /* @__PURE__ */ jsx(
108
+ AutoField,
109
+ {
110
+ field: {
111
+ type: field.type,
112
+ label: "Default Value",
113
+ options: (currentFieldSettings == null ? void 0 : currentFieldSettings.options) || []
114
+ },
115
+ value,
116
+ onChange,
117
+ readOnly: false,
118
+ id
119
+ }
120
+ )
121
+ };
122
+ fieldSettings.options = {
123
+ type: "array",
124
+ label: "Options",
125
+ defaultItemProps: {
126
+ label: "New Option",
127
+ value: "new"
128
+ },
129
+ arrayFields: {
130
+ label: { type: "text", label: "Label" },
131
+ value: {
132
+ type: "text",
133
+ label: "Value"
134
+ }
135
+ },
136
+ getItemSummary(item, index) {
137
+ return item.label || `Option ${(index || 0) + 1}`;
138
+ }
139
+ };
140
+ break;
141
+ case "array":
142
+ fieldSettings.summary = {
143
+ type: "select",
144
+ label: "Summary Field",
145
+ options: [
146
+ {
147
+ label: "Default Numbering",
148
+ value: ""
149
+ },
150
+ ...((currentFieldSettings == null ? void 0 : currentFieldSettings.subFields) || []).map((f) => ({
151
+ label: f.name,
152
+ value: f.name
153
+ }))
154
+ ]
155
+ };
156
+ case "object":
157
+ fieldSettings.subFields = {
158
+ type: "array",
159
+ label: "Sub Fields",
160
+ defaultItemProps: {
161
+ name: "New Sub Field",
162
+ type: "text"
163
+ },
164
+ arrayFields: {
165
+ name: { type: "text", label: "Name" },
166
+ type: {
167
+ type: "select",
168
+ options: deep ? [
169
+ {
170
+ label: "Text",
171
+ value: "text"
172
+ },
173
+ {
174
+ label: "Number",
175
+ value: "number"
176
+ },
177
+ {
178
+ label: "Select",
179
+ value: "select"
180
+ },
181
+ {
182
+ label: "Radio",
183
+ value: "radio"
184
+ }
185
+ ] : [
186
+ {
187
+ label: "Text",
188
+ value: "text"
189
+ },
190
+ {
191
+ label: "Number",
192
+ value: "number"
193
+ },
194
+ {
195
+ label: "Select",
196
+ value: "select"
197
+ },
198
+ {
199
+ label: "Radio",
200
+ value: "radio"
201
+ },
202
+ {
203
+ label: "Array",
204
+ value: "array"
205
+ },
206
+ {
207
+ label: "Object",
208
+ value: "object"
209
+ },
210
+ {
211
+ label: "Reference",
212
+ value: "reference"
213
+ }
214
+ ]
215
+ }
216
+ },
217
+ getItemSummary(item, index) {
218
+ return item.name || `Field ${(index || 0) + 1}`;
219
+ }
220
+ };
221
+ if (!deep)
222
+ fieldSettings.subFieldSettings = {
223
+ type: "object",
224
+ label: "Sub Field Settings",
225
+ objectFields: (currentFieldSettings == null ? void 0 : currentFieldSettings.subFields) ? getFieldSettings(
226
+ currentFieldSettings.subFields,
227
+ currentFieldSettings.subFieldSettings,
228
+ true
229
+ ) : {}
230
+ };
231
+ break;
232
+ }
233
+ fields[field.name] = {
234
+ type: "object",
235
+ label: field.name,
236
+ objectFields: fieldSettings
237
+ };
238
+ return fields;
239
+ }, {});
240
+ };
241
+ var get_field_settings_default = getFieldSettings;
242
+
243
+ // src/puck/lib/get-settings-by-path.ts
244
+ function getFieldSettingsByPath(fieldSettings, path) {
245
+ return path.split(".").reduce((o, key) => o ? o[key] : void 0, fieldSettings);
246
+ }
247
+
248
+ // src/puck/lib/set-prop-by-path.ts
249
+ function setPropertyByPath(props, path, value) {
250
+ const parts = path.split(".");
251
+ const last = parts.pop();
252
+ let cur = props;
253
+ for (const p of parts) {
254
+ if (typeof cur[p] !== "object" || cur[p] === null) cur[p] = {};
255
+ cur = cur[p];
256
+ }
257
+ cur[last] = value;
258
+ }
259
+
260
+ // src/puck/lib/builder/root-config.tsx
261
+ import { useEffect } from "react";
262
+
263
+ // src/puck/context/useStore.ts
264
+ import { createContext, useContext } from "react";
265
+ import { useStore } from "zustand";
266
+ var appStoreContext = createContext(createSoftConfigStore());
267
+ var createUseSoftConfig = () => {
268
+ return function useSoftConfig2(selector) {
269
+ const context = useContext(appStoreContext);
270
+ return useStore(context, selector);
271
+ };
272
+ };
273
+ var useSoftConfig = createUseSoftConfig();
274
+
275
+ // src/puck/lib/builder/root-config.tsx
276
+ import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
277
+ var useCustomPuck = createUsePuck();
278
+ var breakVersion = (version) => {
279
+ const [major, minor, patch] = version.split(".").map((v) => parseInt(v));
280
+ return [major, minor, patch];
281
+ };
282
+ var updateVersion = (version, increment) => {
283
+ let [major, minor, patch] = breakVersion(version);
284
+ if (increment === "major") {
285
+ major += 1;
286
+ minor = 0;
287
+ patch = 0;
288
+ } else if (increment === "minor") {
289
+ minor += 1;
290
+ patch = 0;
291
+ } else {
292
+ patch += 1;
293
+ }
294
+ return `${major}.${minor}.${patch}`;
295
+ };
296
+ var builderRootConfig = (config, overrides, editingComponent) => ({
297
+ fields: {
298
+ _name: {
299
+ type: "text",
300
+ label: "Soft Component Name"
301
+ },
302
+ _fields: {
303
+ type: "array",
304
+ label: "Fields",
305
+ defaultItemProps: {
306
+ name: "New Field",
307
+ type: "text"
308
+ },
309
+ getItemSummary(item, index) {
310
+ return item.name || `Field ${(index || 0) + 1}`;
311
+ },
312
+ arrayFields: {
313
+ name: { type: "text", label: "Name" },
314
+ type: {
315
+ type: "select",
316
+ label: "Type",
317
+ options: [
318
+ { label: "Text", value: "text" },
319
+ { label: "Textarea", value: "textarea" },
320
+ { label: "Number", value: "number" },
321
+ { label: "Select", value: "select" },
322
+ { label: "Radio", value: "radio" },
323
+ { label: "Array", value: "array" },
324
+ { label: "Object", value: "object" }
325
+ // { label: "Reference", value: "reference" },
326
+ ]
327
+ }
328
+ }
329
+ }
330
+ },
331
+ resolveFields({ props: data }, { fields, changed }) {
332
+ var _a, _b;
333
+ if (!(data == null ? void 0 : data._fields) || changed._fields || changed._fieldSettings)
334
+ if ((_a = data == null ? void 0 : data._fields) == null ? void 0 : _a.length)
335
+ fields._fieldSettings = {
336
+ type: "object",
337
+ label: "Field Settings",
338
+ objectFields: get_field_settings_default(
339
+ data._fields || [],
340
+ data._fieldSettings || {}
341
+ )
342
+ };
343
+ else delete fields._fieldSettings;
344
+ if (((_b = data == null ? void 0 : data._versions) == null ? void 0 : _b.length) && (!(data == null ? void 0 : data._version) || changed._version || changed._fieldSettings)) {
345
+ const latestVersion = data._versions[data._versions.length - 1] || "1.0.0";
346
+ delete fields._version;
347
+ fields._version = {
348
+ type: "select",
349
+ label: "Version",
350
+ options: [
351
+ ...data._versions.map((v) => ({ label: v, value: v })),
352
+ {
353
+ label: `${updateVersion(latestVersion, "patch")} (Patch)`,
354
+ value: updateVersion(latestVersion, "patch")
355
+ },
356
+ {
357
+ label: `${updateVersion(latestVersion, "minor")} (Minor)`,
358
+ value: updateVersion(latestVersion, "minor")
359
+ },
360
+ {
361
+ label: `${updateVersion(latestVersion, "major")} (Major)`,
362
+ value: updateVersion(latestVersion, "major")
363
+ }
364
+ ]
365
+ };
366
+ }
367
+ return fields;
368
+ },
369
+ resolveData: (props) => {
370
+ return {
371
+ props,
372
+ readOnly: Boolean(editingComponent) ? {
373
+ _name: true
374
+ } : void 0
375
+ };
376
+ },
377
+ render: (props) => {
378
+ const fieldSettings = props == null ? void 0 : props._fieldSettings;
379
+ const data = useCustomPuck((s) => s.appState.data);
380
+ const dispatch = useCustomPuck((s) => s.dispatch);
381
+ const getSelectorForId = useCustomPuck((s) => s.getSelectorForId);
382
+ const setVersion = useSoftConfig((s) => s.builder.setVersion);
383
+ const state = useSoftConfig((s) => s.state);
384
+ useEffect(() => {
385
+ const propagateChanges = setTimeout(() => {
386
+ if (!fieldSettings || Object.keys(fieldSettings).length === 0) return;
387
+ walkTree(
388
+ data,
389
+ {
390
+ components: config.components
391
+ },
392
+ (content) => content.map((child) => {
393
+ var _a;
394
+ const map = ((_a = child.props) == null ? void 0 : _a._map) || [];
395
+ if (map.length) {
396
+ map.forEach(({ from, to, transform }) => {
397
+ if (!from || !to) return;
398
+ const fromPaths = Array.isArray(from) ? from : [from];
399
+ const toPaths = Array.isArray(to) ? to : [to];
400
+ const inputValues = fromPaths.map(
401
+ (f) => getFieldSettingsByPath(props._fieldSettings || {}, f)
402
+ );
403
+ console.log(inputValues);
404
+ let value = transform ? transform(
405
+ inputValues.map((v) => v == null ? void 0 : v.defaultValue),
406
+ child.props
407
+ ) : inputValues[0];
408
+ if (Array.isArray(value)) {
409
+ value.forEach((val, i) => {
410
+ if (toPaths[i]) {
411
+ const originalValue = getFieldSettingsByPath(
412
+ child.props,
413
+ toPaths[i]
414
+ );
415
+ if (originalValue !== val) {
416
+ const itemSelector = getSelectorForId(child.props.id);
417
+ if (!itemSelector) return;
418
+ setPropertyByPath(child.props, toPaths[i], val);
419
+ dispatch({
420
+ type: "replace",
421
+ data: child,
422
+ destinationIndex: itemSelector == null ? void 0 : itemSelector.index,
423
+ destinationZone: itemSelector == null ? void 0 : itemSelector.zone
424
+ });
425
+ }
426
+ }
427
+ });
428
+ } else if (toPaths[0]) {
429
+ const setting = getFieldSettingsByPath(
430
+ fieldSettings,
431
+ fromPaths.length === 1 ? fromPaths[0] : fromPaths.join(".")
432
+ );
433
+ const defaultValue = setting == null ? void 0 : setting.defaultValue;
434
+ const originalValue = getFieldSettingsByPath(
435
+ child.props,
436
+ toPaths[0]
437
+ );
438
+ const finalValue = transform !== void 0 && value !== void 0 ? value : defaultValue !== void 0 ? defaultValue : value;
439
+ if (originalValue !== finalValue) {
440
+ const itemSelector = getSelectorForId(child.props.id);
441
+ if (!itemSelector) return;
442
+ setPropertyByPath(child.props, toPaths[0], finalValue);
443
+ dispatch({
444
+ type: "replace",
445
+ data: child,
446
+ destinationIndex: itemSelector == null ? void 0 : itemSelector.index,
447
+ destinationZone: itemSelector == null ? void 0 : itemSelector.zone
448
+ });
449
+ }
450
+ }
451
+ });
452
+ }
453
+ return child;
454
+ })
455
+ );
456
+ }, 300);
457
+ return () => clearTimeout(propagateChanges);
458
+ }, [fieldSettings]);
459
+ useEffect(() => {
460
+ var _a;
461
+ if (state !== "remodeling") return;
462
+ if (!(props == null ? void 0 : props._version) || !(props == null ? void 0 : props._name)) return;
463
+ const currentVersion = props == null ? void 0 : props._version;
464
+ if (((_a = props._versions) == null ? void 0 : _a.includes(currentVersion)) && props._versions.length > 1) {
465
+ setVersion(props._name, currentVersion, props, dispatch);
466
+ }
467
+ }, [props == null ? void 0 : props._version]);
468
+ return /* @__PURE__ */ jsx2(Fragment, { children: props.children });
469
+ }
470
+ });
471
+
472
+ // src/puck/lib/builder/generate-field-options.ts
473
+ function generateFieldOptions(fields, selectedFields, prefix = "") {
474
+ const opts = [];
475
+ function recurse(current, prefix2) {
476
+ Object.entries(current).forEach(([key, fld]) => {
477
+ if (fld.type === "slot") return;
478
+ if (key === "_map") return;
479
+ if (key === "_slotEnabled") return;
480
+ const path = prefix2 ? `${prefix2}.${key}` : key;
481
+ if (selectedFields.includes(path)) {
482
+ return;
483
+ }
484
+ opts.push({ label: path, value: path });
485
+ if (fld.type === "object" && fld.objectFields) {
486
+ recurse(fld.objectFields, path);
487
+ }
488
+ if (fld.type === "array" && fld.arrayFields) {
489
+ recurse(fld.arrayFields, path);
490
+ }
491
+ });
492
+ }
493
+ recurse(fields, prefix);
494
+ return opts;
495
+ }
496
+ function generateDynamicFieldOptions(_fields, _fieldSettings, prefix = "") {
497
+ const opts = [];
498
+ if (!_fields || !_fieldSettings) return opts;
499
+ function recurse(fields, fieldSettings, currentPrefix) {
500
+ fields.forEach((field) => {
501
+ var _a;
502
+ const settings = fieldSettings[field.name];
503
+ const path = currentPrefix ? `${currentPrefix}.${field.name}` : field.name;
504
+ opts.push({ label: path, value: path });
505
+ if ((_a = settings == null ? void 0 : settings.subFields) == null ? void 0 : _a.length) {
506
+ recurse(settings.subFields, settings.subFieldSettings || {}, path);
507
+ }
508
+ });
509
+ }
510
+ recurse(_fields, _fieldSettings, prefix);
511
+ return opts;
512
+ }
513
+
514
+ // src/puck/components/error-boundary/index.tsx
515
+ import { Component } from "react";
516
+
517
+ // src/puck/lib/get-class-name-factory.ts
518
+ import classnames from "classnames";
519
+ var getClassNameFactory = (rootClass, styles, config = { baseClass: "" }) => (options = {}) => {
520
+ if (typeof options === "string") {
521
+ const descendant = options;
522
+ const style = styles[`${rootClass}-${descendant}`];
523
+ if (style) {
524
+ return config.baseClass + styles[`${rootClass}-${descendant}`] || "";
525
+ }
526
+ return "";
527
+ } else if (typeof options === "object") {
528
+ const modifiers = options;
529
+ const prefixedModifiers = {};
530
+ for (let modifier in modifiers) {
531
+ prefixedModifiers[styles[`${rootClass}--${modifier}`]] = modifiers[modifier];
532
+ }
533
+ const c = styles[rootClass];
534
+ return config.baseClass + classnames(__spreadValues({
535
+ [c]: !!c
536
+ }, prefixedModifiers));
537
+ } else {
538
+ return config.baseClass + styles[rootClass] || "";
539
+ }
540
+ };
541
+ var get_class_name_factory_default = getClassNameFactory;
542
+
543
+ // src/puck/components/error-boundary/styles.module.css
544
+ var styles_default = {};
545
+
546
+ // src/puck/components/error-boundary/index.tsx
547
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
548
+ var getClassName = get_class_name_factory_default("ErrorBoundary", styles_default);
549
+ var ErrorBoundary = class extends Component {
550
+ constructor(props) {
551
+ super(props);
552
+ this.resetError = () => {
553
+ this.setState({
554
+ hasError: false,
555
+ error: null
556
+ });
557
+ };
558
+ this.state = {
559
+ hasError: false,
560
+ error: null
561
+ };
562
+ }
563
+ static getDerivedStateFromError(error) {
564
+ return {
565
+ hasError: true,
566
+ error
567
+ };
568
+ }
569
+ componentDidCatch(error, errorInfo) {
570
+ console.error("Error caught by ErrorBoundary:", error, errorInfo);
571
+ }
572
+ render() {
573
+ if (this.state.hasError) {
574
+ if (typeof this.props.fallback === "function") {
575
+ return this.props.fallback(this.state.error, this.resetError);
576
+ }
577
+ if (this.props.fallback) {
578
+ return this.props.fallback;
579
+ }
580
+ return /* @__PURE__ */ jsxs("div", { className: getClassName(), children: [
581
+ /* @__PURE__ */ jsx3("h3", { className: getClassName("title"), children: "Component Error" }),
582
+ /* @__PURE__ */ jsxs("details", { className: getClassName("details"), children: [
583
+ /* @__PURE__ */ jsx3("summary", { children: "Show error details" }),
584
+ this.state.error && this.state.error.toString()
585
+ ] }),
586
+ /* @__PURE__ */ jsx3(
587
+ "button",
588
+ {
589
+ onClick: this.resetError,
590
+ className: getClassName("button"),
591
+ children: "Try Again"
592
+ }
593
+ )
594
+ ] });
595
+ }
596
+ return this.props.children;
597
+ }
598
+ };
599
+
600
+ // src/puck/lib/builder/builder-config.tsx
601
+ import { jsx as jsx4 } from "react/jsx-runtime";
602
+ var builderConfig = (config, overrides, editingComponent) => ({
603
+ root: builderRootConfig(config, overrides, editingComponent),
604
+ components: Object.entries(__spreadValues({}, config.components)).reduce(
605
+ (acc, [name, component]) => {
606
+ if (!editingComponent || name !== editingComponent) {
607
+ let _a;
608
+ const tempComponent = __spreadProps(__spreadValues({}, component), {
609
+ resolveFields(data, params) {
610
+ return __async(this, null, function* () {
611
+ let fields = {};
612
+ if (!fields._slot) {
613
+ const slotFields = Object.entries(params.fields).filter(
614
+ ([_, field]) => field.type === "slot"
615
+ );
616
+ if (slotFields.length)
617
+ fields._slot = {
618
+ type: "array",
619
+ label: "Enable Dropdown Slots",
620
+ getItemSummary(item, index) {
621
+ return item.slot || `Slot ${(index || 0) + 1}`;
622
+ },
623
+ arrayFields: {
624
+ slot: {
625
+ type: "select",
626
+ label: "Slot",
627
+ options: [
628
+ { label: "Select a slot", value: "" },
629
+ ...slotFields.filter(
630
+ ([fieldName, field]) => {
631
+ var _a2;
632
+ return field.type === "slot" && !(((_a2 = data.props) == null ? void 0 : _a2._slot) || []).some(
633
+ (s) => s.slot === fieldName
634
+ );
635
+ }
636
+ ).map(([fieldName, field]) => ({
637
+ label: field.label || fieldName,
638
+ value: fieldName
639
+ }))
640
+ ]
641
+ },
642
+ name: {
643
+ type: "text",
644
+ label: "Name",
645
+ placeholder: "Optional Slot Name"
646
+ }
647
+ }
648
+ };
649
+ }
650
+ const defaultFields = component.resolveFields ? yield component.resolveFields(data, params) : component.fields || {};
651
+ if (!fields._map) {
652
+ const rootProps = getRootProps(params.appState);
653
+ fields._map = overrides.map ? {
654
+ type: "custom",
655
+ render: ({ value, onChange, id }) => {
656
+ return overrides.map({
657
+ rootProps,
658
+ value,
659
+ onChange,
660
+ id,
661
+ props: data.props || {},
662
+ fromOptions: generateDynamicFieldOptions(
663
+ (rootProps == null ? void 0 : rootProps._fields) || [],
664
+ (rootProps == null ? void 0 : rootProps._fieldSettings) || {}
665
+ ),
666
+ toOptions: generateFieldOptions(defaultFields, [])
667
+ });
668
+ }
669
+ } : {
670
+ type: "array",
671
+ label: "Dynamic Field Map",
672
+ arrayFields: {
673
+ from: {
674
+ type: "select",
675
+ label: "From",
676
+ options: [
677
+ { label: "Select a field", value: "" },
678
+ ...generateDynamicFieldOptions(
679
+ (rootProps == null ? void 0 : rootProps._fields) || [],
680
+ (rootProps == null ? void 0 : rootProps._fieldSettings) || {}
681
+ )
682
+ ]
683
+ },
684
+ to: {
685
+ type: "select",
686
+ label: "To",
687
+ options: [
688
+ { label: "Select a field", value: "" },
689
+ ...generateFieldOptions(defaultFields, [])
690
+ ]
691
+ }
692
+ }
693
+ };
694
+ }
695
+ fields = __spreadValues(__spreadValues({}, fields), defaultFields);
696
+ return fields;
697
+ });
698
+ },
699
+ resolveData: ({ props }, { lastData }) => {
700
+ var _a2;
701
+ const _map = props._map || [];
702
+ const readOnlyFields = _map.flatMap((item) => item.to);
703
+ if (_map.length) {
704
+ return {
705
+ props,
706
+ readOnly: readOnlyFields.reduce(
707
+ (acc2, field) => __spreadProps(__spreadValues({}, acc2), { [field]: true }),
708
+ {}
709
+ )
710
+ };
711
+ }
712
+ const prevMap = (_a2 = lastData == null ? void 0 : lastData.props) == null ? void 0 : _a2._map;
713
+ if (prevMap && prevMap.length === 1) {
714
+ const lastField = prevMap[0].to;
715
+ if (typeof lastField === "string") {
716
+ return {
717
+ props,
718
+ readOnly: { [lastField]: false }
719
+ };
720
+ }
721
+ if (Array.isArray(lastField)) {
722
+ return {
723
+ props,
724
+ readOnly: lastField.reduce(
725
+ (acc2, field) => __spreadProps(__spreadValues({}, acc2), { [String(field)]: false }),
726
+ {}
727
+ )
728
+ };
729
+ }
730
+ }
731
+ return {
732
+ props,
733
+ readOnly: {}
734
+ };
735
+ },
736
+ render: (props) => {
737
+ return /* @__PURE__ */ jsx4(ErrorBoundary, { children: component.render(props) });
738
+ }
739
+ });
740
+ acc[name] = tempComponent;
741
+ }
742
+ return acc;
743
+ },
744
+ {}
745
+ )
746
+ });
747
+
748
+ // src/puck/lib/soft-component-from-appstate.ts
749
+ var getSubComponents = (content, componentConfigs, fieldSettings, slots) => {
750
+ if (!content || !Array.isArray(content)) return [];
751
+ return content.map((componentProps) => {
752
+ var _a, _b, _c;
753
+ const componentConfig = componentConfigs[componentProps.type];
754
+ const enabledSlotNames = new Set(
755
+ (((_a = componentProps.props) == null ? void 0 : _a._slot) || []).map((s) => s.slot)
756
+ );
757
+ const components = Object.entries((componentConfig == null ? void 0 : componentConfig.fields) || {}).filter(
758
+ ([key, field]) => field.type === "slot" && !enabledSlotNames.has(key)
759
+ // Skip if slot is enabled
760
+ ).reduce(
761
+ (acc, [fieldKey, _]) => {
762
+ var _a2;
763
+ acc[fieldKey] = getSubComponents(
764
+ ((_a2 = componentProps.props) == null ? void 0 : _a2[fieldKey]) || [],
765
+ componentConfigs,
766
+ fieldSettings,
767
+ slots
768
+ );
769
+ return acc;
770
+ },
771
+ {}
772
+ ) || {};
773
+ const fixedProps = __spreadValues(__spreadValues({}, componentConfig == null ? void 0 : componentConfig.defaultProps), componentProps.props);
774
+ (componentProps.props._slot || []).forEach(
775
+ (s) => {
776
+ var _a2;
777
+ if (s.slot)
778
+ slots[s.name || `${componentProps.props.id}-${s.slot}`] = componentProps.props[s.slot] || ((_a2 = componentConfig == null ? void 0 : componentConfig.defaultProps) == null ? void 0 : _a2[s.slot]);
779
+ }
780
+ );
781
+ const subComponent = {
782
+ map: ((_b = componentProps.props) == null ? void 0 : _b._map) || [],
783
+ fixedProps,
784
+ type: componentProps.type,
785
+ components,
786
+ enabledSlots: ((_c = componentProps.props) == null ? void 0 : _c._slot) || []
787
+ };
788
+ return subComponent;
789
+ });
790
+ };
791
+ var softFieldsToPuckFields = (fields, fieldSettings) => {
792
+ return (fields == null ? void 0 : fields.reduce(
793
+ (acc, field) => {
794
+ var _a, _b, _c, _d, _e, _f, _g, _h;
795
+ switch (field.type) {
796
+ case "text":
797
+ case "textarea":
798
+ acc[field.name] = { type: field.type, label: field.name };
799
+ break;
800
+ case "number":
801
+ acc[field.name] = {
802
+ type: field.type,
803
+ label: field.name,
804
+ min: (_a = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _a.min,
805
+ max: (_b = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _b.max,
806
+ step: (_c = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _c.step
807
+ };
808
+ break;
809
+ case "select":
810
+ case "radio":
811
+ acc[field.name] = {
812
+ type: field.type,
813
+ label: field.name,
814
+ options: ((_d = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _d.options) || []
815
+ };
816
+ break;
817
+ // TODO: Default item props
818
+ case "array":
819
+ acc[field.name] = {
820
+ type: field.type,
821
+ label: field.name,
822
+ arrayFields: softFieldsToPuckFields(
823
+ ((_e = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _e.subFields) || [],
824
+ ((_f = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _f.subFieldSettings) || {}
825
+ )
826
+ };
827
+ break;
828
+ // TODO: Needs testing to see if it works
829
+ case "object":
830
+ acc[field.name] = {
831
+ type: field.type,
832
+ label: field.name,
833
+ objectFields: softFieldsToPuckFields(
834
+ ((_g = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _g.subFields) || [],
835
+ ((_h = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _h.subFieldSettings) || {}
836
+ )
837
+ };
838
+ break;
839
+ default:
840
+ acc[field.name] = { type: "text", label: field.name };
841
+ }
842
+ return acc;
843
+ },
844
+ {}
845
+ )) || {};
846
+ };
847
+ var softComponentFromAppState = (appState, configComponents) => {
848
+ var _a;
849
+ const rootProps = ((_a = appState.data.root) == null ? void 0 : _a.props) || {};
850
+ const fields = rootProps._fields || [];
851
+ const field_settings = rootProps._fieldSettings || {};
852
+ const slots = {};
853
+ const components = getSubComponents(
854
+ appState.data.content || [],
855
+ configComponents,
856
+ field_settings,
857
+ slots
858
+ );
859
+ const defaultProps = __spreadValues(__spreadValues({}, Object.keys(field_settings).reduce(
860
+ (acc, field) => {
861
+ acc[field] = field_settings[field].defaultValue;
862
+ return acc;
863
+ },
864
+ {}
865
+ )), slots);
866
+ return [
867
+ {
868
+ fields: __spreadValues(__spreadValues({}, softFieldsToPuckFields(fields, field_settings)), Object.keys(slots).reduce((acc, slot) => {
869
+ acc[slot] = { type: "slot", label: slot };
870
+ return acc;
871
+ }, {})),
872
+ defaultProps,
873
+ components,
874
+ slots
875
+ },
876
+ rootProps._version || "1.0.0"
877
+ ];
878
+ };
879
+
880
+ // src/puck/lib/soft-component-to-appstate.ts
881
+ var puckFieldsToSoftFields = (fields, slots) => {
882
+ const softFields = [];
883
+ const fieldSettings = {};
884
+ Object.entries(fields).forEach(([fieldName, field]) => {
885
+ if (slots.has(fieldName)) {
886
+ return;
887
+ }
888
+ if (fieldName === "_version") {
889
+ return;
890
+ }
891
+ switch (field.type) {
892
+ case "text":
893
+ case "textarea":
894
+ softFields.push({ name: fieldName, type: field.type });
895
+ break;
896
+ case "number":
897
+ softFields.push({ name: fieldName, type: "number" });
898
+ fieldSettings[fieldName] = {
899
+ min: field.min,
900
+ max: field.max,
901
+ step: field.step
902
+ };
903
+ break;
904
+ case "select":
905
+ case "radio":
906
+ softFields.push({ name: fieldName, type: field.type });
907
+ fieldSettings[fieldName] = {
908
+ options: field.options || []
909
+ };
910
+ break;
911
+ case "array":
912
+ softFields.push({ name: fieldName, type: "array" });
913
+ const arrayFieldsResult = puckFieldsToSoftFields(
914
+ field.arrayFields || {},
915
+ /* @__PURE__ */ new Set()
916
+ );
917
+ fieldSettings[fieldName] = {
918
+ subFields: arrayFieldsResult.fields,
919
+ subFieldSettings: arrayFieldsResult.fieldSettings
920
+ };
921
+ break;
922
+ case "object":
923
+ softFields.push({ name: fieldName, type: "object" });
924
+ const objectFieldsResult = puckFieldsToSoftFields(
925
+ field.objectFields || {},
926
+ /* @__PURE__ */ new Set()
927
+ );
928
+ fieldSettings[fieldName] = {
929
+ subFields: objectFieldsResult.fields,
930
+ subFieldSettings: objectFieldsResult.fieldSettings
931
+ };
932
+ break;
933
+ default:
934
+ softFields.push({ name: fieldName, type: "text" });
935
+ }
936
+ if (fieldSettings[fieldName]) {
937
+ fieldSettings[fieldName].defaultValue = void 0;
938
+ } else {
939
+ fieldSettings[fieldName] = { defaultValue: void 0 };
940
+ }
941
+ });
942
+ return { fields: softFields, fieldSettings };
943
+ };
944
+ var reconstructComponents = (subComponents, componentConfigs, softComponentProps) => {
945
+ return subComponents.map((subComponent) => {
946
+ const componentConfig = componentConfigs[subComponent.type];
947
+ const props = __spreadValues({}, subComponent.fixedProps);
948
+ subComponent.map.forEach(({ from, to }) => {
949
+ if (softComponentProps[from] !== void 0) {
950
+ props[to] = softComponentProps[from];
951
+ }
952
+ });
953
+ if (subComponent.enabledSlots.length > 0) {
954
+ props._slot = subComponent.enabledSlots;
955
+ subComponent.enabledSlots.forEach(({ slot, name }) => {
956
+ const slotName = name || `${props.id}-${slot}`;
957
+ if (softComponentProps[slotName] !== void 0) {
958
+ props[slot] = softComponentProps[slotName];
959
+ }
960
+ });
961
+ }
962
+ Object.entries(subComponent.components).forEach(([slotKey, nestedComponents]) => {
963
+ if (nestedComponents.length > 0) {
964
+ props[slotKey] = reconstructComponents(
965
+ nestedComponents,
966
+ componentConfigs,
967
+ softComponentProps
968
+ );
969
+ } else {
970
+ props[slotKey] = [];
971
+ }
972
+ });
973
+ const componentData = {
974
+ type: subComponent.type,
975
+ props: __spreadValues({
976
+ id: props.id || ""
977
+ }, props)
978
+ };
979
+ return componentData;
980
+ });
981
+ };
982
+ var softComponentToAppState = (softComponent, componentName, version, versions, componentProps, componentConfigs) => {
983
+ const slots = new Set(Object.keys(softComponent.slots));
984
+ const { fields, fieldSettings } = puckFieldsToSoftFields(
985
+ softComponent.fields,
986
+ slots
987
+ );
988
+ Object.entries(softComponent.defaultProps).forEach(([key, value]) => {
989
+ if (fieldSettings && fieldSettings[key] && !slots.has(key)) {
990
+ fieldSettings[key].defaultValue = value;
991
+ }
992
+ });
993
+ const rootProps = {
994
+ _name: componentName,
995
+ _version: version,
996
+ _versions: versions,
997
+ _fields: fields,
998
+ _fieldSettings: fieldSettings
999
+ };
1000
+ const content = reconstructComponents(
1001
+ softComponent.components,
1002
+ componentConfigs,
1003
+ componentProps
1004
+ );
1005
+ return {
1006
+ root: {
1007
+ props: __spreadValues({
1008
+ title: "Soft Component Builder"
1009
+ }, rootProps)
1010
+ },
1011
+ content
1012
+ };
1013
+ };
1014
+
1015
+ // src/puck/lib/root-droppable-id.ts
1016
+ var rootAreaId = "root";
1017
+ var rootZone = "default-zone";
1018
+ var rootDroppableId = `${rootAreaId}:${rootZone}`;
1019
+
1020
+ // src/puck/components/soft-render/index.tsx
1021
+ import { useMemo, useRef } from "react";
1022
+ import { v4 as uuidv4 } from "uuid";
1023
+ import { Fragment as Fragment2, jsx as jsx5 } from "react/jsx-runtime";
1024
+ function SoftRender({
1025
+ softComponentFields,
1026
+ softSubComponent,
1027
+ configComponents,
1028
+ props,
1029
+ depth = 0
1030
+ }) {
1031
+ const _a = props, { id, puck, editMode } = _a, rest = __objRest(_a, ["id", "puck", "editMode"]);
1032
+ const mapCacheRef = useRef(/* @__PURE__ */ new Map());
1033
+ const prevPropsRef = useRef("");
1034
+ const propsSnapshot = JSON.stringify(props);
1035
+ if (prevPropsRef.current !== propsSnapshot) {
1036
+ mapCacheRef.current.clear();
1037
+ prevPropsRef.current = propsSnapshot;
1038
+ }
1039
+ const subComponentRootProps = useMemo(
1040
+ () => Object.entries(softComponentFields || {}).filter(([_, field]) => field.type !== "slot").reduce(
1041
+ (acc, [fieldKey]) => {
1042
+ acc[fieldKey] = props[fieldKey];
1043
+ return acc;
1044
+ },
1045
+ {}
1046
+ ),
1047
+ [softComponentFields, props]
1048
+ );
1049
+ const valuesToUpdateKey = useMemo(
1050
+ () => JSON.stringify(subComponentRootProps),
1051
+ [subComponentRootProps]
1052
+ );
1053
+ return /* @__PURE__ */ jsx5(Fragment2, { children: (softSubComponent == null ? void 0 : softSubComponent.length) > 0 && softSubComponent.map((subComponent, index) => {
1054
+ var _a2;
1055
+ const componentConfig = configComponents[subComponent == null ? void 0 : subComponent.type];
1056
+ if (!componentConfig) return null;
1057
+ const resolvedProps = subComponent.fixedProps || {};
1058
+ const stableId = useMemo(
1059
+ () => depth === 0 ? id : `${subComponent.type}-${id}-d${depth}-${uuidv4()}`,
1060
+ [id, depth, subComponent.type]
1061
+ );
1062
+ if ((_a2 = subComponent.map) == null ? void 0 : _a2.length) {
1063
+ subComponent.map.forEach(({ from, to, transform }) => {
1064
+ const fromPaths = Array.isArray(from) ? from : from ? [from] : [];
1065
+ const toPaths = Array.isArray(to) ? to : to ? [to] : [];
1066
+ const inputValues = fromPaths.map(
1067
+ (f) => getFieldSettingsByPath(props || {}, f)
1068
+ );
1069
+ const cacheKey = JSON.stringify(inputValues);
1070
+ let result = mapCacheRef.current.get(cacheKey);
1071
+ if (!result) {
1072
+ result = transform ? transform(inputValues, props) : inputValues[0];
1073
+ mapCacheRef.current.set(cacheKey, result);
1074
+ }
1075
+ if (Array.isArray(result)) {
1076
+ result.forEach(
1077
+ (val, i) => toPaths[i] && setPropertyByPath(resolvedProps, toPaths[i], val)
1078
+ );
1079
+ } else if (toPaths[0]) {
1080
+ setPropertyByPath(resolvedProps, toPaths[0], result);
1081
+ }
1082
+ });
1083
+ }
1084
+ Object.entries(componentConfig.fields || {}).forEach(
1085
+ ([slotKey, field]) => {
1086
+ var _a3, _b;
1087
+ if (field.type === "slot") {
1088
+ const enabledSlot = (_a3 = subComponent == null ? void 0 : subComponent.enabledSlots) == null ? void 0 : _a3.find(
1089
+ (s) => s.slot === slotKey
1090
+ );
1091
+ if (enabledSlot) {
1092
+ const slotName = enabledSlot.name || `${(_b = subComponent.fixedProps) == null ? void 0 : _b.id}-${slotKey}`;
1093
+ resolvedProps[slotKey] = useMemo(
1094
+ () => rest[slotName] || (() => null),
1095
+ [slotName]
1096
+ );
1097
+ } else {
1098
+ resolvedProps[slotKey] = useMemo(() => {
1099
+ return ({
1100
+ className,
1101
+ style
1102
+ }) => {
1103
+ var _a4, _b2;
1104
+ return /* @__PURE__ */ jsx5("div", { className, style, children: /* @__PURE__ */ jsx5(
1105
+ SoftRender,
1106
+ {
1107
+ softComponentFields,
1108
+ softSubComponent: (_b2 = (_a4 = subComponent == null ? void 0 : subComponent.components) == null ? void 0 : _a4[slotKey]) != null ? _b2 : [],
1109
+ configComponents,
1110
+ props,
1111
+ depth: depth + 1
1112
+ },
1113
+ slotKey
1114
+ ) });
1115
+ };
1116
+ }, [valuesToUpdateKey]);
1117
+ }
1118
+ }
1119
+ }
1120
+ );
1121
+ const ComponentRender = componentConfig.render;
1122
+ return /* @__PURE__ */ jsx5(ErrorBoundary, { children: /* @__PURE__ */ jsx5(
1123
+ ComponentRender,
1124
+ __spreadValues({
1125
+ id: stableId,
1126
+ editMode,
1127
+ puck
1128
+ }, resolvedProps)
1129
+ ) }, index);
1130
+ }) });
1131
+ }
1132
+
1133
+ // src/puck/lib/create-versioned-component-config.tsx
1134
+ import { jsx as jsx6 } from "react/jsx-runtime";
1135
+ var createVersionedComponentConfig = (componentName, version, allVersions, config, softComponents, defaultProps) => {
1136
+ var _a, _b;
1137
+ const softConfig = config;
1138
+ return {
1139
+ fields: Object.fromEntries(
1140
+ (Object.entries(
1141
+ (_b = (_a = softComponents[componentName].versions) == null ? void 0 : _a[version]) == null ? void 0 : _b.fields
1142
+ ) || []).filter(
1143
+ ([key, field]) => field.type === "slot"
1144
+ ).map(([key, field]) => [key, __spreadValues({}, field)])
1145
+ ),
1146
+ defaultProps: __spreadProps(__spreadValues({}, defaultProps), {
1147
+ version
1148
+ }),
1149
+ resolveFields: (data) => {
1150
+ var _a2, _b2;
1151
+ const selectedVersion = ((_a2 = data.props) == null ? void 0 : _a2.version) || version;
1152
+ const versionedComponent = (_b2 = softComponents[componentName]) == null ? void 0 : _b2.versions[selectedVersion];
1153
+ const fieldsWithoutSlots = Object.fromEntries(
1154
+ Object.entries((versionedComponent == null ? void 0 : versionedComponent.fields) || {}).filter(([, field]) => field.type !== "slot").map(([key, field]) => [key, __spreadValues({}, field)])
1155
+ );
1156
+ return __spreadValues({
1157
+ version: {
1158
+ label: "Version",
1159
+ type: "select",
1160
+ options: allVersions.map((v) => ({ label: v, value: v }))
1161
+ }
1162
+ }, fieldsWithoutSlots);
1163
+ },
1164
+ render: (props) => {
1165
+ var _a2;
1166
+ const selectedVersion = props.version || version;
1167
+ const versionedComponent = (_a2 = softComponents[componentName]) == null ? void 0 : _a2.versions[selectedVersion];
1168
+ return /* @__PURE__ */ jsx6(
1169
+ SoftRender,
1170
+ {
1171
+ softComponentFields: versionedComponent.fields,
1172
+ softSubComponent: versionedComponent.components,
1173
+ configComponents: softConfig.components,
1174
+ props
1175
+ }
1176
+ );
1177
+ }
1178
+ };
1179
+ };
1180
+
1181
+ // src/puck/lib/generate-id.ts
1182
+ import { v4 as uuidv42 } from "uuid";
1183
+ var generateId = (type) => type ? `${type}-${uuidv42()}` : uuidv42();
1184
+
1185
+ // src/puck/lib/builder/sub-component-decomposer.tsx
1186
+ var subComponentDecomposer = (componentRootData, softSubComponent) => {
1187
+ const resolvedProps = __spreadValues({}, softSubComponent.fixedProps);
1188
+ softSubComponent.map.forEach((mapItem) => {
1189
+ var _a;
1190
+ const value = (_a = componentRootData.props) == null ? void 0 : _a[mapItem.from || ""];
1191
+ if (value !== void 0) {
1192
+ resolvedProps[mapItem.to] = value;
1193
+ }
1194
+ });
1195
+ softSubComponent.enabledSlots.forEach(({ slot, name }) => {
1196
+ var _a, _b;
1197
+ const referenceName = name || `${(_a = softSubComponent.fixedProps) == null ? void 0 : _a.id}-${slot}`;
1198
+ resolvedProps[slot] = ((_b = componentRootData.props) == null ? void 0 : _b[referenceName]) || [];
1199
+ });
1200
+ Object.entries(softSubComponent.components).forEach(
1201
+ ([slotKey, subComponents]) => {
1202
+ resolvedProps[slotKey] = subComponents.map(
1203
+ (subComponent) => subComponentDecomposer(componentRootData, subComponent)
1204
+ );
1205
+ }
1206
+ );
1207
+ const accItem = {
1208
+ type: softSubComponent.type,
1209
+ props: __spreadProps(__spreadValues({}, resolvedProps), {
1210
+ id: generateId(softSubComponent.type)
1211
+ })
1212
+ };
1213
+ return accItem;
1214
+ };
1215
+
1216
+ // src/puck/lib/decompose-soft-component.ts
1217
+ function decomposeSoftComponent(componentData, softComponents) {
1218
+ var _a, _b;
1219
+ if (!(componentData == null ? void 0 : componentData.type) || !(componentData == null ? void 0 : componentData.props.id)) {
1220
+ throw new Error("Component data must have type and id to decompose.");
1221
+ }
1222
+ const version = ((_a = componentData.props) == null ? void 0 : _a.version) || "1.0.0";
1223
+ const softComponent = (_b = softComponents[componentData.type]) == null ? void 0 : _b.versions[version];
1224
+ if (!softComponent) {
1225
+ throw new Error(
1226
+ `Soft component "${componentData.type}" version "${version}" not found.`
1227
+ );
1228
+ }
1229
+ const decomposedComponentData = softComponent.components.map(
1230
+ (softSubComponent) => {
1231
+ return subComponentDecomposer(componentData, softSubComponent);
1232
+ }
1233
+ );
1234
+ return decomposedComponentData;
1235
+ }
1236
+ function isSoftComponent(componentType, softComponents) {
1237
+ return componentType in softComponents;
1238
+ }
1239
+
1240
+ // src/puck/lib/demolish-soft-component.ts
1241
+ import { walkTree as walkTree2 } from "@measured/puck";
1242
+ function demolishSoftComponent(componentName, data, config, softComponents) {
1243
+ const resolvedData = walkTree2(data, config, (components) => {
1244
+ components.forEach((componentData, index) => {
1245
+ if (componentData.type === componentName) {
1246
+ const decomposed = decomposeSoftComponent(componentData, softComponents);
1247
+ if (decomposed.length) {
1248
+ components.splice(index, 1, ...decomposed);
1249
+ }
1250
+ }
1251
+ });
1252
+ return components;
1253
+ });
1254
+ const newSoftComponents = __spreadValues({}, softComponents);
1255
+ delete newSoftComponents[componentName];
1256
+ const newConfig = __spreadProps(__spreadValues({}, config), {
1257
+ components: Object.entries(config.components).reduce(
1258
+ (acc, [name, component]) => {
1259
+ if (name !== componentName) {
1260
+ acc[name] = component;
1261
+ }
1262
+ return acc;
1263
+ },
1264
+ {}
1265
+ )
1266
+ });
1267
+ return {
1268
+ data: resolvedData,
1269
+ config: newConfig,
1270
+ softComponents: newSoftComponents
1271
+ };
1272
+ }
1273
+
1274
+ // src/puck/store/slices/builder.tsx
1275
+ var createBuildersSlice = (set, get, initialConfig) => ({
1276
+ build: (history, selectedItem, itemSelector, puckDispatch) => {
1277
+ if (!selectedItem || !itemSelector) {
1278
+ throw new Error("No item selected to build from.");
1279
+ }
1280
+ puckDispatch({
1281
+ type: "set",
1282
+ state: (previous) => ({
1283
+ ui: __spreadProps(__spreadValues({}, previous.ui), {
1284
+ itemSelector: null
1285
+ }),
1286
+ data: __spreadProps(__spreadValues({}, previous.data), {
1287
+ root: {
1288
+ props: {
1289
+ _name: "New Soft Component"
1290
+ }
1291
+ },
1292
+ content: [__spreadValues({}, selectedItem)]
1293
+ })
1294
+ })
1295
+ });
1296
+ const config = __spreadValues({}, get().softConfig);
1297
+ const overrides = get().overrides;
1298
+ const buildConfig = builderConfig(config, overrides);
1299
+ set((s) => __spreadProps(__spreadValues({}, s), {
1300
+ softConfig: buildConfig,
1301
+ storedConfig: config,
1302
+ originalHistory: history,
1303
+ itemSelector: {
1304
+ index: itemSelector.index,
1305
+ zone: itemSelector.zone || rootDroppableId
1306
+ },
1307
+ state: "building"
1308
+ }));
1309
+ setTimeout(
1310
+ () => puckDispatch({
1311
+ type: "replaceRoot",
1312
+ root: {
1313
+ title: "Soft Component Builder",
1314
+ _name: "New Soft Component"
1315
+ }
1316
+ }),
1317
+ 100
1318
+ );
1319
+ },
1320
+ remodel: (history, selectedItem, itemSelector, puckDispatch) => {
1321
+ var _a, _b;
1322
+ if (!selectedItem || !itemSelector) {
1323
+ throw new Error("No item selected to build from.");
1324
+ }
1325
+ const softComponentName = selectedItem.type;
1326
+ if (!softComponentName) {
1327
+ throw new Error("Selected item must have a valid component type.");
1328
+ }
1329
+ const softComponentVersion = ((_a = selectedItem.props) == null ? void 0 : _a.version) || "1.0.0";
1330
+ const softComponent = (_b = get().softComponents[softComponentName]) == null ? void 0 : _b.versions[softComponentVersion];
1331
+ const versions = Object.keys(
1332
+ get().softComponents[softComponentName].versions || {}
1333
+ );
1334
+ if (!softComponent) {
1335
+ throw new Error(
1336
+ `Soft component "${softComponentName}" with version "${softComponentVersion}" not found.`
1337
+ );
1338
+ }
1339
+ puckDispatch({
1340
+ type: "setUi",
1341
+ ui: (previous) => __spreadProps(__spreadValues({}, previous), {
1342
+ itemSelector: void 0
1343
+ })
1344
+ });
1345
+ const { root, content } = softComponentToAppState(
1346
+ softComponent,
1347
+ softComponentName,
1348
+ softComponentVersion,
1349
+ versions,
1350
+ selectedItem.props,
1351
+ get().softConfig.components
1352
+ );
1353
+ puckDispatch({
1354
+ type: "setData",
1355
+ data: (previous) => __spreadProps(__spreadValues({}, previous), {
1356
+ root: __spreadProps(__spreadValues({}, root), { _versions: versions }),
1357
+ content: content || []
1358
+ })
1359
+ });
1360
+ const config = __spreadValues({}, get().softConfig);
1361
+ const overrides = get().overrides;
1362
+ const buildConfig = builderConfig(config, overrides, softComponentName);
1363
+ set((s) => __spreadProps(__spreadValues({}, s), {
1364
+ storedConfig: config,
1365
+ softConfig: buildConfig,
1366
+ originalHistory: history,
1367
+ itemSelector: {
1368
+ index: itemSelector.index,
1369
+ zone: itemSelector.zone || rootDroppableId
1370
+ },
1371
+ state: "remodeling"
1372
+ }));
1373
+ setTimeout(
1374
+ () => puckDispatch({
1375
+ type: "replaceRoot",
1376
+ root: {
1377
+ title: "Soft Component Builder",
1378
+ _name: "New Soft Component"
1379
+ }
1380
+ }),
1381
+ 100
1382
+ );
1383
+ },
1384
+ complete: (appState, setHistories) => {
1385
+ var _a, _b;
1386
+ if (get().state === "ready") {
1387
+ throw new Error("Not building or remodeling a component.");
1388
+ }
1389
+ const componentName = (_b = (_a = appState.data.root) == null ? void 0 : _a.props) == null ? void 0 : _b._name;
1390
+ if (!componentName) {
1391
+ throw new Error("Root component must have a name to compose.");
1392
+ }
1393
+ const [newSoftComponentConfig, version] = get().builder.compose(appState, componentName) || [];
1394
+ if (!newSoftComponentConfig) {
1395
+ throw new Error("Failed to compose new soft component config.");
1396
+ }
1397
+ const storedHistories = get().originalHistory;
1398
+ setHistories([...storedHistories]);
1399
+ const config = __spreadValues({}, get().softConfig || initialConfig);
1400
+ set((s) => __spreadProps(__spreadValues({}, s), {
1401
+ softConfig: __spreadProps(__spreadValues({}, config), {
1402
+ root: __spreadValues({}, initialConfig.root),
1403
+ components: __spreadProps(__spreadValues({}, Object.entries(config.components).reduce(
1404
+ (acc, [name, component]) => {
1405
+ var _a2;
1406
+ let tempComponent = (_a2 = config.components) == null ? void 0 : _a2[name];
1407
+ if (tempComponent) {
1408
+ acc[name] = tempComponent;
1409
+ acc[name].render = tempComponent.render;
1410
+ } else {
1411
+ tempComponent = __spreadValues({}, component);
1412
+ tempComponent == null ? true : delete tempComponent.resolvePermissions;
1413
+ tempComponent == null ? true : delete tempComponent.resolveData;
1414
+ acc[name] = tempComponent;
1415
+ }
1416
+ return acc;
1417
+ },
1418
+ {}
1419
+ )), {
1420
+ [componentName]: __spreadValues({}, newSoftComponentConfig)
1421
+ })
1422
+ }),
1423
+ storedConfig: void 0,
1424
+ state: "inspecting",
1425
+ originalHistory: []
1426
+ }));
1427
+ return componentName;
1428
+ },
1429
+ inspect: (componentName, puckDispatch) => {
1430
+ if (get().state !== "inspecting") {
1431
+ throw new Error("Not in inspecting state.");
1432
+ }
1433
+ const selector = __spreadValues({}, get().itemSelector);
1434
+ if ((selector == null ? void 0 : selector.index) === void 0 || !(selector == null ? void 0 : selector.zone)) {
1435
+ throw new Error("No selector found for last item.");
1436
+ }
1437
+ setTimeout(() => {
1438
+ puckDispatch({
1439
+ type: "remove",
1440
+ index: selector.index,
1441
+ zone: selector.zone
1442
+ });
1443
+ puckDispatch({
1444
+ type: "insert",
1445
+ destinationIndex: selector.index,
1446
+ destinationZone: selector.zone,
1447
+ componentType: componentName
1448
+ });
1449
+ }, 500);
1450
+ set((s) => __spreadProps(__spreadValues({}, s), {
1451
+ state: "ready",
1452
+ setItemSelector: void 0,
1453
+ setOriginalItem: void 0
1454
+ }));
1455
+ },
1456
+ cancel: (setHistories) => {
1457
+ const storedHistories = get().originalHistory;
1458
+ setTimeout(() => setHistories([...storedHistories]), 100);
1459
+ set((s) => __spreadProps(__spreadValues({}, s), {
1460
+ softConfig: get().storedConfig || initialConfig,
1461
+ storedConfig: void 0,
1462
+ originalHistory: [],
1463
+ itemSelector: null,
1464
+ originalItem: null,
1465
+ state: "ready"
1466
+ }));
1467
+ },
1468
+ compose: (appState, componentName) => {
1469
+ if (!componentName) {
1470
+ throw new Error("Root component must have a name to compose.");
1471
+ }
1472
+ const componentConfigs = get().softConfig.components;
1473
+ if (get().state === "building" && Object.keys(componentConfigs).includes(componentName)) {
1474
+ throw new Error(
1475
+ `Component name "${componentName}" already exists in the configuration.`
1476
+ );
1477
+ }
1478
+ const [softComponent, version] = softComponentFromAppState(appState, componentConfigs);
1479
+ const existingComponent = get().softComponents[componentName];
1480
+ const allVersions = Object.keys((existingComponent == null ? void 0 : existingComponent.versions) || {});
1481
+ const isNewVersion = !allVersions.includes(version);
1482
+ const newSoftComponentConfig = createVersionedComponentConfig(
1483
+ componentName,
1484
+ version,
1485
+ isNewVersion ? [...allVersions, version] : allVersions,
1486
+ get().softConfig,
1487
+ __spreadProps(__spreadValues({}, get().softComponents), {
1488
+ [componentName]: __spreadProps(__spreadValues({}, existingComponent), {
1489
+ versions: __spreadProps(__spreadValues({}, existingComponent == null ? void 0 : existingComponent.versions), {
1490
+ [version]: softComponent
1491
+ })
1492
+ })
1493
+ }),
1494
+ softComponent.defaultProps
1495
+ );
1496
+ get().setSoftComponent(componentName, version, softComponent);
1497
+ return [newSoftComponentConfig, version];
1498
+ },
1499
+ decompose: (componentData) => {
1500
+ if (!(componentData == null ? void 0 : componentData.type) || !(componentData == null ? void 0 : componentData.props.id)) {
1501
+ throw new Error("Component data must have type and id to decompose.");
1502
+ }
1503
+ return decomposeSoftComponent(componentData, get().softComponents);
1504
+ },
1505
+ demolish: (componentName, data, puckDispatch) => {
1506
+ if (get().state !== "ready") {
1507
+ throw new Error("Components can only be demolished in ready state.");
1508
+ }
1509
+ const result = demolishSoftComponent(
1510
+ componentName,
1511
+ data,
1512
+ get().softConfig,
1513
+ get().softComponents
1514
+ );
1515
+ puckDispatch({
1516
+ type: "setData",
1517
+ data: result.data
1518
+ });
1519
+ set((s) => __spreadProps(__spreadValues({}, s), {
1520
+ softComponents: result.softComponents,
1521
+ softConfig: result.config
1522
+ }));
1523
+ },
1524
+ setVersion: (componentName, newVersion, currentProps, puckDispatch) => {
1525
+ var _a;
1526
+ if (get().state !== "remodeling") {
1527
+ throw new Error("Can only switch versions during remodeling.");
1528
+ }
1529
+ const softComponent = (_a = get().softComponents[componentName]) == null ? void 0 : _a.versions[newVersion];
1530
+ if (!softComponent) {
1531
+ throw new Error(
1532
+ `Soft component "${componentName}" with version "${newVersion}" not found.`
1533
+ );
1534
+ }
1535
+ const versions = Object.keys(
1536
+ get().softComponents[componentName].versions || {}
1537
+ );
1538
+ const { root, content } = softComponentToAppState(
1539
+ softComponent,
1540
+ componentName,
1541
+ newVersion,
1542
+ versions,
1543
+ currentProps,
1544
+ get().softConfig.components
1545
+ );
1546
+ puckDispatch({
1547
+ type: "setData",
1548
+ data: (previous) => __spreadProps(__spreadValues({}, previous), {
1549
+ root: __spreadProps(__spreadValues({}, root), { props: __spreadProps(__spreadValues({}, root.props), { _versions: versions }) }),
1550
+ content: content || []
1551
+ })
1552
+ });
1553
+ }
1554
+ });
1555
+
1556
+ // src/puck/lib/build-initial-soft-components.ts
1557
+ function extractDependencies(softComponents, componentName, version) {
1558
+ var _a, _b;
1559
+ const dependencies = /* @__PURE__ */ new Set();
1560
+ const component = (_b = (_a = softComponents[componentName]) == null ? void 0 : _a.versions) == null ? void 0 : _b[version];
1561
+ if (!component) {
1562
+ return dependencies;
1563
+ }
1564
+ const processSubComponents = (subComponents) => {
1565
+ if (!Array.isArray(subComponents)) return;
1566
+ for (const subComponent of subComponents) {
1567
+ if (subComponent == null ? void 0 : subComponent.type) {
1568
+ dependencies.add(subComponent.type);
1569
+ if (subComponent.components) {
1570
+ Object.values(subComponent.components).forEach((nestedComponents) => {
1571
+ processSubComponents(nestedComponents);
1572
+ });
1573
+ }
1574
+ }
1575
+ }
1576
+ };
1577
+ processSubComponents(component.components);
1578
+ return dependencies;
1579
+ }
1580
+ function topologicalSort(softComponents, hardComponentNames) {
1581
+ const sorted = [];
1582
+ const visiting = /* @__PURE__ */ new Set();
1583
+ const visited = /* @__PURE__ */ new Set();
1584
+ const dependencyGraph = /* @__PURE__ */ new Map();
1585
+ for (const [componentName, component] of Object.entries(softComponents)) {
1586
+ const defaultVersion = component.defaultVersion || Object.keys(component.versions || {}).pop();
1587
+ if (!defaultVersion) continue;
1588
+ const allDeps = extractDependencies(
1589
+ softComponents,
1590
+ componentName,
1591
+ defaultVersion
1592
+ );
1593
+ const softDeps = new Set(
1594
+ [...allDeps].filter((dep) => !hardComponentNames.has(dep))
1595
+ );
1596
+ dependencyGraph.set(componentName, softDeps);
1597
+ }
1598
+ function visit(componentName) {
1599
+ if (visited.has(componentName)) return;
1600
+ if (visiting.has(componentName)) {
1601
+ throw new Error(
1602
+ `Circular dependency detected involving component: ${componentName}`
1603
+ );
1604
+ }
1605
+ visiting.add(componentName);
1606
+ const dependencies = dependencyGraph.get(componentName) || /* @__PURE__ */ new Set();
1607
+ for (const dep of dependencies) {
1608
+ if (softComponents[dep]) {
1609
+ visit(dep);
1610
+ }
1611
+ }
1612
+ visiting.delete(componentName);
1613
+ visited.add(componentName);
1614
+ sorted.push(componentName);
1615
+ }
1616
+ for (const componentName of Object.keys(softComponents)) {
1617
+ if (!visited.has(componentName)) {
1618
+ visit(componentName);
1619
+ }
1620
+ }
1621
+ return sorted;
1622
+ }
1623
+ function buildInitialSoftComponents(hardConfig, softComponents) {
1624
+ var _a, _b;
1625
+ if (!softComponents || Object.keys(softComponents).length === 0) {
1626
+ return {};
1627
+ }
1628
+ const hardComponentNames = new Set(Object.keys(hardConfig.components || {}));
1629
+ try {
1630
+ const sortedComponentNames = topologicalSort(
1631
+ softComponents,
1632
+ hardComponentNames
1633
+ );
1634
+ const buildingConfig = __spreadProps(__spreadValues({}, hardConfig), {
1635
+ components: __spreadValues({}, hardConfig.components)
1636
+ });
1637
+ const componentConfigs = {};
1638
+ for (const name of sortedComponentNames) {
1639
+ const comp = softComponents[name];
1640
+ const defaultVersion = comp.defaultVersion || Object.keys(comp.versions || {}).pop();
1641
+ const versionedComponent = (_a = comp.versions) == null ? void 0 : _a[defaultVersion || ""];
1642
+ const allVersions = Object.keys(comp.versions || {});
1643
+ if (!versionedComponent) {
1644
+ console.warn(
1645
+ `Soft component "${name}" does not have a valid default version. Skipping.`
1646
+ );
1647
+ continue;
1648
+ }
1649
+ const newSoftComponentConfig = createVersionedComponentConfig(
1650
+ name,
1651
+ defaultVersion || "1.0.0",
1652
+ allVersions,
1653
+ buildingConfig,
1654
+ // Pass the accumulating config
1655
+ softComponents,
1656
+ versionedComponent.defaultProps
1657
+ );
1658
+ componentConfigs[name] = newSoftComponentConfig;
1659
+ buildingConfig.components[name] = newSoftComponentConfig;
1660
+ }
1661
+ return componentConfigs;
1662
+ } catch (error) {
1663
+ console.error("Error building soft components:", error);
1664
+ console.warn("Falling back to unordered component building");
1665
+ const componentConfigs = {};
1666
+ for (const [name, comp] of Object.entries(softComponents)) {
1667
+ const defaultVersion = comp.defaultVersion || Object.keys(comp.versions || {}).pop();
1668
+ const versionedComponent = (_b = comp.versions) == null ? void 0 : _b[defaultVersion || ""];
1669
+ const allVersions = Object.keys(comp.versions || {});
1670
+ if (!versionedComponent) {
1671
+ console.warn(
1672
+ `Soft component "${name}" does not have a valid default version. Skipping.`
1673
+ );
1674
+ continue;
1675
+ }
1676
+ const newSoftComponentConfig = createVersionedComponentConfig(
1677
+ name,
1678
+ defaultVersion || "1.0.0",
1679
+ allVersions,
1680
+ hardConfig,
1681
+ softComponents,
1682
+ versionedComponent.defaultProps
1683
+ );
1684
+ componentConfigs[name] = newSoftComponentConfig;
1685
+ }
1686
+ return componentConfigs;
1687
+ }
1688
+ }
1689
+
1690
+ // src/puck/store/index.tsx
1691
+ var createSoftConfigStore = (hardConfig = {
1692
+ components: {}
1693
+ }, softComponents = {}, overrides = {}) => create()(
1694
+ subscribeWithSelector(
1695
+ devtools((set, get) => ({
1696
+ state: "ready",
1697
+ originalHistory: [],
1698
+ overrides,
1699
+ storeHistory: (history) => set({ originalHistory: history }),
1700
+ removeHistory: () => set({ originalHistory: [] }),
1701
+ itemSelector: null,
1702
+ setItemSelector: (selector) => set({ itemSelector: selector }),
1703
+ originalItem: null,
1704
+ setOriginalItem: (item) => set({ originalItem: item }),
1705
+ softComponents: __spreadValues({}, softComponents),
1706
+ softConfig: __spreadProps(__spreadValues({}, hardConfig), {
1707
+ components: __spreadValues(__spreadValues({}, hardConfig.components), buildInitialSoftComponents(hardConfig, softComponents))
1708
+ }),
1709
+ setSoftComponent: (name, version, component) => {
1710
+ set((state) => {
1711
+ var _a;
1712
+ return {
1713
+ softComponents: __spreadProps(__spreadValues({}, state.softComponents), {
1714
+ [name]: {
1715
+ defaultVersion: version,
1716
+ versions: __spreadProps(__spreadValues({}, ((_a = state.softComponents[name]) == null ? void 0 : _a.versions) || {}), {
1717
+ [version]: component
1718
+ })
1719
+ }
1720
+ })
1721
+ };
1722
+ });
1723
+ },
1724
+ setSoftComponentDefaultVersion: (name, version) => {
1725
+ var _a, _b, _c;
1726
+ const softComponent = (_b = (_a = get().softComponents[name]) == null ? void 0 : _a.versions) == null ? void 0 : _b[version];
1727
+ const allVersions = Object.keys(
1728
+ ((_c = get().softComponents[name]) == null ? void 0 : _c.versions) || {}
1729
+ );
1730
+ if (!softComponent) {
1731
+ throw new Error(
1732
+ `Soft component "${name}" version "${version}" does not exist.`
1733
+ );
1734
+ }
1735
+ const newSoftComponentConfig = createVersionedComponentConfig(
1736
+ name,
1737
+ version,
1738
+ allVersions,
1739
+ get().softConfig,
1740
+ get().softComponents,
1741
+ softComponent.defaultProps
1742
+ );
1743
+ set((state) => ({
1744
+ softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
1745
+ components: __spreadProps(__spreadValues({}, state.softConfig.components), {
1746
+ [name]: newSoftComponentConfig
1747
+ })
1748
+ }),
1749
+ softComponents: __spreadProps(__spreadValues({}, state.softComponents), {
1750
+ [name]: __spreadProps(__spreadValues({}, state.softComponents[name]), {
1751
+ defaultVersion: version
1752
+ })
1753
+ })
1754
+ }));
1755
+ },
1756
+ removeSoftComponentVersion: (key, version) => {
1757
+ set((state) => {
1758
+ const component = state.softComponents[key];
1759
+ if (!component) return {};
1760
+ const newVersions = Object.fromEntries(
1761
+ Object.entries(component.versions || {}).filter(
1762
+ ([k, _]) => k !== version
1763
+ )
1764
+ );
1765
+ let newDefaultVersion = component.defaultVersion;
1766
+ if (component.defaultVersion === version) {
1767
+ const versionKeys = Object.keys(newVersions);
1768
+ newDefaultVersion = versionKeys.length > 0 ? versionKeys[versionKeys.length - 1] : "";
1769
+ }
1770
+ return {
1771
+ softComponents: __spreadProps(__spreadValues({}, state.softComponents), {
1772
+ [key]: __spreadProps(__spreadValues({}, component), {
1773
+ versions: newVersions,
1774
+ defaultVersion: newDefaultVersion
1775
+ })
1776
+ })
1777
+ };
1778
+ });
1779
+ },
1780
+ removeSoftComponent: (key) => {
1781
+ set((state) => ({
1782
+ softComponents: Object.fromEntries(
1783
+ Object.entries(state.softComponents).filter(([k, _]) => k !== key)
1784
+ )
1785
+ }));
1786
+ },
1787
+ setSoftComponentConfig: (key, config, category) => {
1788
+ set((state) => {
1789
+ var _a;
1790
+ return {
1791
+ softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
1792
+ components: __spreadProps(__spreadValues({}, state.softConfig.components), {
1793
+ [key]: __spreadValues({}, config)
1794
+ }),
1795
+ categories: category && state.softConfig.categories ? __spreadProps(__spreadValues({}, state.softConfig.categories), {
1796
+ [category]: __spreadProps(__spreadValues({}, state.softConfig.categories[category]), {
1797
+ components: [
1798
+ ...((_a = state.softConfig.categories[category]) == null ? void 0 : _a.components) || [],
1799
+ key
1800
+ ]
1801
+ })
1802
+ }) : state.softConfig.categories
1803
+ })
1804
+ };
1805
+ });
1806
+ },
1807
+ removeSoftComponentConfig: (key) => {
1808
+ set((state) => ({
1809
+ softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
1810
+ components: Object.fromEntries(
1811
+ Object.entries(state.softConfig.components).filter(
1812
+ ([k, _]) => k !== key
1813
+ )
1814
+ )
1815
+ })
1816
+ }));
1817
+ },
1818
+ setSoftCategoryConfig: (key, category) => {
1819
+ set((state) => {
1820
+ var _a;
1821
+ return {
1822
+ softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
1823
+ categories: __spreadProps(__spreadValues({}, state.softConfig.categories), {
1824
+ [key]: __spreadValues(__spreadValues({}, (_a = state.softConfig.categories) == null ? void 0 : _a[key]), category)
1825
+ })
1826
+ })
1827
+ };
1828
+ });
1829
+ },
1830
+ removeSoftCategoryConfig: (key) => {
1831
+ set((state) => ({
1832
+ softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
1833
+ categories: Object.fromEntries(
1834
+ Object.entries(state.softConfig.categories || {}).filter(
1835
+ ([k, _]) => k !== key
1836
+ )
1837
+ )
1838
+ })
1839
+ }));
1840
+ },
1841
+ builder: createBuildersSlice(set, get, hardConfig)
1842
+ }))
1843
+ )
1844
+ );
1845
+
1846
+ // src/puck/context/storeProvider.tsx
1847
+ import { useEffect as useEffect2, useMemo as useMemo2, useState as useState2 } from "react";
1848
+ import { jsx as jsx7 } from "react/jsx-runtime";
1849
+ var SoftConfigProvider = ({
1850
+ children,
1851
+ hardConfig,
1852
+ softComponents,
1853
+ overrides
1854
+ }) => {
1855
+ const store = useMemo2(
1856
+ () => createSoftConfigStore(hardConfig, softComponents, overrides),
1857
+ [hardConfig, softComponents, overrides]
1858
+ );
1859
+ const [softConfig, setSoftConfig] = useState2(
1860
+ () => store.getState().softConfig
1861
+ );
1862
+ const [internalSoftComponents, setSoftComponents] = useState2(
1863
+ () => store.getState().softComponents
1864
+ );
1865
+ useEffect2(() => {
1866
+ const unsubscribe = store.subscribe(() => {
1867
+ setSoftConfig(store.getState().softConfig);
1868
+ setSoftComponents(store.getState().softComponents);
1869
+ });
1870
+ return () => {
1871
+ unsubscribe();
1872
+ };
1873
+ }, [store]);
1874
+ return /* @__PURE__ */ jsx7(appStoreContext.Provider, { value: store, children: children(softConfig, internalSoftComponents) });
1875
+ };
1876
+
1877
+ // src/puck/actions/useBuild.tsx
1878
+ import { createUsePuck as createUsePuck2 } from "@measured/puck";
1879
+
1880
+ // src/puck/lib/notify.ts
1881
+ var customHandler = null;
1882
+ var defaultHandler = (message, type) => {
1883
+ if (type === "error") {
1884
+ console.error(`[Error] ${message}`);
1885
+ } else {
1886
+ console.log(`[Success] ${message}`);
1887
+ }
1888
+ };
1889
+ var setNotificationHandler = (handler) => {
1890
+ customHandler = handler;
1891
+ };
1892
+ var notify = {
1893
+ error: (message) => {
1894
+ const handler = customHandler || defaultHandler;
1895
+ handler(message, "error");
1896
+ },
1897
+ success: (message) => {
1898
+ const handler = customHandler || defaultHandler;
1899
+ handler(message, "success");
1900
+ }
1901
+ };
1902
+
1903
+ // src/puck/actions/useBuild.tsx
1904
+ var useCustomPuck2 = createUsePuck2();
1905
+ var useBuild = () => {
1906
+ const build = useSoftConfig((s) => s.builder.build);
1907
+ const history = useCustomPuck2((s) => s.history.histories);
1908
+ const selectedItem = useCustomPuck2((s) => s.selectedItem);
1909
+ const itemSelector = useCustomPuck2((s) => s.appState.ui.itemSelector);
1910
+ const dispatch = useCustomPuck2((s) => s.dispatch);
1911
+ const status = useSoftConfig((s) => s.state);
1912
+ const handleBuild = () => {
1913
+ if (status !== "ready") {
1914
+ notify.error("Can only build when in ready state.");
1915
+ return;
1916
+ }
1917
+ try {
1918
+ build(history, selectedItem, itemSelector, dispatch);
1919
+ } catch (error) {
1920
+ console.error("Failed to build:", error);
1921
+ notify.error(
1922
+ "Failed to build: " + (error instanceof Error ? error.message : String(error))
1923
+ );
1924
+ }
1925
+ };
1926
+ return { handleBuild, canBuild: status === "ready" };
1927
+ };
1928
+
1929
+ // src/puck/actions/useRemodel.tsx
1930
+ import { createUsePuck as createUsePuck3 } from "@measured/puck";
1931
+ var useCustomPuck3 = createUsePuck3();
1932
+ var useRemodel = () => {
1933
+ const remodel = useSoftConfig((s) => s.builder.remodel);
1934
+ const history = useCustomPuck3((s) => s.history.histories);
1935
+ const selectedItem = useCustomPuck3((s) => s.selectedItem);
1936
+ const itemSelector = useCustomPuck3((s) => s.appState.ui.itemSelector);
1937
+ const dispatch = useCustomPuck3((s) => s.dispatch);
1938
+ const status = useSoftConfig((s) => s.state);
1939
+ const softComponents = useSoftConfig((s) => s.softComponents);
1940
+ const handleRemodel = (componentName) => {
1941
+ if (status !== "ready") {
1942
+ notify.error("Can only remodel when in ready state.");
1943
+ return;
1944
+ }
1945
+ const name = componentName || (selectedItem == null ? void 0 : selectedItem.type);
1946
+ if (!name || !Object.keys(softComponents).includes(name)) {
1947
+ notify.error("Selected component is not a soft component.");
1948
+ return;
1949
+ }
1950
+ try {
1951
+ remodel(history, selectedItem, itemSelector, dispatch);
1952
+ } catch (error) {
1953
+ console.error("Failed to remodel:", error);
1954
+ notify.error(
1955
+ "Failed to remodel: " + (error instanceof Error ? error.message : String(error))
1956
+ );
1957
+ }
1958
+ };
1959
+ const canRemodel = (componentName) => {
1960
+ const name = componentName || (selectedItem == null ? void 0 : selectedItem.type);
1961
+ return status === "ready" && name !== void 0 && Object.keys(softComponents).includes(name);
1962
+ };
1963
+ return { handleRemodel, canRemodel };
1964
+ };
1965
+
1966
+ // src/puck/actions/useComplete.tsx
1967
+ import { createUsePuck as createUsePuck4 } from "@measured/puck";
1968
+ import { useState as useState3, useCallback } from "react";
1969
+ var useCustomPuck4 = createUsePuck4();
1970
+ var useComplete = () => {
1971
+ const complete = useSoftConfig((s) => s.builder.complete);
1972
+ const appState = useCustomPuck4((s) => s.appState);
1973
+ const setHistories = useCustomPuck4((s) => s.history.setHistories);
1974
+ const status = useSoftConfig((s) => s.state);
1975
+ const [newComponent, setNewComponent] = useState3(null);
1976
+ const handleComplete = useCallback(() => {
1977
+ if (status === "ready") {
1978
+ notify.error("Not building or remodeling a component.");
1979
+ return null;
1980
+ }
1981
+ try {
1982
+ const componentName = complete(appState, setHistories);
1983
+ setNewComponent(componentName);
1984
+ return componentName;
1985
+ } catch (error) {
1986
+ console.error("Failed to complete:", error);
1987
+ notify.error(
1988
+ "Failed to complete: " + (error instanceof Error ? error.message : String(error))
1989
+ );
1990
+ return null;
1991
+ }
1992
+ }, [complete, appState, setHistories, status]);
1993
+ const canComplete = status === "building" || status === "remodeling";
1994
+ return { handleComplete, canComplete, newComponent, setNewComponent };
1995
+ };
1996
+
1997
+ // src/puck/actions/useCancel.tsx
1998
+ import { createUsePuck as createUsePuck5 } from "@measured/puck";
1999
+ var useCustomPuck5 = createUsePuck5();
2000
+ var useCancel = () => {
2001
+ const cancel = useSoftConfig((s) => s.builder.cancel);
2002
+ const setHistories = useCustomPuck5((s) => s.history.setHistories);
2003
+ const status = useSoftConfig((s) => s.state);
2004
+ const handleCancel = () => {
2005
+ if (status === "ready") {
2006
+ notify.error("Nothing to cancel.");
2007
+ return;
2008
+ }
2009
+ try {
2010
+ cancel(setHistories);
2011
+ } catch (error) {
2012
+ console.error("Failed to cancel:", error);
2013
+ notify.error(
2014
+ "Failed to cancel: " + (error instanceof Error ? error.message : String(error))
2015
+ );
2016
+ }
2017
+ };
2018
+ const canCancel = status === "building" || status === "remodeling";
2019
+ return { handleCancel, canCancel };
2020
+ };
2021
+
2022
+ // src/puck/actions/useInspect.tsx
2023
+ import { createUsePuck as createUsePuck6 } from "@measured/puck";
2024
+ import { useEffect as useEffect3 } from "react";
2025
+ var useCustomPuck6 = createUsePuck6();
2026
+ var useInspect = (componentName) => {
2027
+ const inspect = useSoftConfig((s) => s.builder.inspect);
2028
+ const dispatch = useCustomPuck6((s) => s.dispatch);
2029
+ const status = useSoftConfig((s) => s.state);
2030
+ useEffect3(() => {
2031
+ if (status !== "inspecting") return;
2032
+ if (!componentName) {
2033
+ notify.error("No component to inspect.");
2034
+ return;
2035
+ }
2036
+ try {
2037
+ inspect(componentName, dispatch);
2038
+ } catch (error) {
2039
+ console.error("Failed to inspect:", error);
2040
+ notify.error(
2041
+ "Failed to inspect: " + (error instanceof Error ? error.message : String(error))
2042
+ );
2043
+ }
2044
+ }, [status, componentName, inspect, dispatch]);
2045
+ };
2046
+
2047
+ // src/puck/actions/useDecompose.tsx
2048
+ import { createUsePuck as createUsePuck7, walkTree as walkTree3 } from "@measured/puck";
2049
+ var useCustomPuck7 = createUsePuck7();
2050
+ var useDecompose = () => {
2051
+ const decompose = useSoftConfig((s) => s.builder.decompose);
2052
+ const appState = useCustomPuck7((s) => s.appState);
2053
+ const dispatch = useCustomPuck7((s) => s.dispatch);
2054
+ const selectedItem = useCustomPuck7((s) => s.selectedItem);
2055
+ const status = useSoftConfig((s) => s.state);
2056
+ const softComponents = useSoftConfig((s) => s.softComponents);
2057
+ const config = useSoftConfig((s) => s.softConfig);
2058
+ const handleDecompose = (componentData) => {
2059
+ if (status !== "ready") {
2060
+ notify.error("Can only decompose when in ready state.");
2061
+ return;
2062
+ }
2063
+ const target = componentData || selectedItem;
2064
+ if (!target) {
2065
+ notify.error("No component selected to decompose.");
2066
+ return;
2067
+ }
2068
+ const componentName = target.type;
2069
+ if (!Object.keys(softComponents).includes(componentName)) {
2070
+ notify.error("Selected component is not a soft component.");
2071
+ return;
2072
+ }
2073
+ try {
2074
+ const decomposedComponents = decompose(target);
2075
+ if (!decomposedComponents || decomposedComponents.length === 0) {
2076
+ notify.error("Nothing to decompose.");
2077
+ return;
2078
+ }
2079
+ const newData = walkTree3(appState.data, config, (components) => {
2080
+ const index = components.findIndex((c) => c.props.id === target.props.id);
2081
+ if (index !== -1) {
2082
+ components.splice(index, 1, ...decomposedComponents);
2083
+ }
2084
+ return components;
2085
+ });
2086
+ dispatch({
2087
+ type: "setData",
2088
+ data: newData
2089
+ });
2090
+ } catch (error) {
2091
+ console.error("Failed to decompose:", error);
2092
+ notify.error(
2093
+ "Failed to decompose: " + (error instanceof Error ? error.message : String(error))
2094
+ );
2095
+ }
2096
+ };
2097
+ const canDecompose = (componentData) => {
2098
+ const target = componentData || selectedItem;
2099
+ return status === "ready" && target !== null && Object.keys(softComponents).includes((target == null ? void 0 : target.type) || "");
2100
+ };
2101
+ return { handleDecompose, canDecompose };
2102
+ };
2103
+
2104
+ // src/puck/actions/useDemolish.tsx
2105
+ import { createUsePuck as createUsePuck8 } from "@measured/puck";
2106
+ var useCustomPuck8 = createUsePuck8();
2107
+ var useDemolish = () => {
2108
+ const demolish = useSoftConfig((s) => s.builder.demolish);
2109
+ const dispatch = useCustomPuck8((s) => s.dispatch);
2110
+ const data = useCustomPuck8((s) => s.appState.data);
2111
+ const status = useSoftConfig((s) => s.state);
2112
+ const softComponents = useSoftConfig((s) => s.softComponents);
2113
+ const handleDemolish = (componentName) => {
2114
+ if (status !== "ready") {
2115
+ notify.error("Can only demolish when in ready state.");
2116
+ return;
2117
+ }
2118
+ if (!Object.keys(softComponents).includes(componentName)) {
2119
+ notify.error("Component is not a soft component.");
2120
+ return;
2121
+ }
2122
+ try {
2123
+ demolish(componentName, data, dispatch);
2124
+ } catch (error) {
2125
+ console.error("Failed to demolish:", error);
2126
+ notify.error(
2127
+ "Failed to demolish: " + (error instanceof Error ? error.message : String(error))
2128
+ );
2129
+ }
2130
+ };
2131
+ const canDemolish = (componentName) => {
2132
+ return status === "ready" && Object.keys(softComponents).includes(componentName);
2133
+ };
2134
+ return { handleDemolish, canDemolish };
2135
+ };
2136
+
2137
+ // src/puck/actions/useSetDefaultVersion.tsx
2138
+ var useSetDefaultVersion = () => {
2139
+ const setSoftComponentDefaultVersion = useSoftConfig(
2140
+ (s) => s.setSoftComponentDefaultVersion
2141
+ );
2142
+ const softComponents = useSoftConfig((s) => s.softComponents);
2143
+ const status = useSoftConfig((s) => s.state);
2144
+ const handleSetDefaultVersion = (componentName, version) => {
2145
+ if (status !== "ready") {
2146
+ return;
2147
+ }
2148
+ if (!Object.keys(softComponents).includes(componentName)) {
2149
+ return;
2150
+ }
2151
+ const component = softComponents[componentName];
2152
+ if (!(component == null ? void 0 : component.versions[version])) {
2153
+ return;
2154
+ }
2155
+ setSoftComponentDefaultVersion(componentName, version);
2156
+ };
2157
+ const canSetDefaultVersion = (componentName, version) => {
2158
+ const component = softComponents[componentName];
2159
+ return status === "ready" && component !== void 0 && component.versions[version] !== void 0 && component.defaultVersion !== version;
2160
+ };
2161
+ const getVersions = (componentName) => {
2162
+ var _a;
2163
+ return Object.keys(((_a = softComponents[componentName]) == null ? void 0 : _a.versions) || {});
2164
+ };
2165
+ const getDefaultVersion = (componentName) => {
2166
+ var _a;
2167
+ return (_a = softComponents[componentName]) == null ? void 0 : _a.defaultVersion;
2168
+ };
2169
+ return {
2170
+ handleSetDefaultVersion,
2171
+ canSetDefaultVersion,
2172
+ getVersions,
2173
+ getDefaultVersion
2174
+ };
2175
+ };
2176
+
2177
+ // src/puck/overrides/Header.tsx
2178
+ import { Button } from "@measured/puck";
2179
+
2180
+ // src/puck/overrides/Header.module.css
2181
+ var Header_default = {};
2182
+
2183
+ // src/puck/actions/usePublish.tsx
2184
+ import { createUsePuck as createUsePuck9 } from "@measured/puck";
2185
+ var useCustomPuck9 = createUsePuck9();
2186
+ var usePublish = () => {
2187
+ const components = useSoftConfig((s) => s.softComponents);
2188
+ const data = useCustomPuck9((s) => s.appState.data);
2189
+ const status = useSoftConfig((s) => s.state);
2190
+ const handlePublish = (publish) => {
2191
+ if (status !== "ready") {
2192
+ notify.error("Can only publish when in ready state.");
2193
+ return;
2194
+ }
2195
+ if (!data) {
2196
+ notify.error("No data to publish.");
2197
+ return;
2198
+ }
2199
+ publish(data, components);
2200
+ };
2201
+ const canPublish = status === "ready";
2202
+ return { handlePublish, canPublish };
2203
+ };
2204
+
2205
+ // src/puck/overrides/Header.tsx
2206
+ import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
2207
+ var getClassName2 = get_class_name_factory_default("Header", Header_default);
2208
+ var Header = ({
2209
+ onPublish,
2210
+ children
2211
+ }) => {
2212
+ const { handleComplete, canComplete, newComponent, setNewComponent } = useComplete();
2213
+ const { handleCancel, canCancel } = useCancel();
2214
+ const { handlePublish } = usePublish();
2215
+ useInspect(newComponent);
2216
+ return /* @__PURE__ */ jsx8("div", { className: getClassName2(), children: canCancel ? /* @__PURE__ */ jsxs2(Fragment3, { children: [
2217
+ /* @__PURE__ */ jsx8(Button, { onClick: handleCancel, children: "Cancel" }),
2218
+ /* @__PURE__ */ jsx8(
2219
+ Button,
2220
+ {
2221
+ variant: "primary",
2222
+ onClick: () => {
2223
+ const name = handleComplete();
2224
+ if (name) {
2225
+ setNewComponent(name);
2226
+ }
2227
+ },
2228
+ children: "Complete"
2229
+ }
2230
+ )
2231
+ ] }) : children ? children : /* @__PURE__ */ jsx8(
2232
+ Button,
2233
+ {
2234
+ variant: "primary",
2235
+ onClick: () => {
2236
+ if (onPublish) {
2237
+ handlePublish(onPublish);
2238
+ }
2239
+ },
2240
+ children: "Publish"
2241
+ }
2242
+ ) });
2243
+ };
2244
+
2245
+ // src/puck/overrides/ActionBar.tsx
2246
+ import { ActionBar } from "@measured/puck";
2247
+ import { Combine, ComponentIcon, EditIcon } from "lucide-react";
2248
+
2249
+ // src/puck/overrides/ActionBar.module.css
2250
+ var ActionBar_default = {};
2251
+
2252
+ // src/puck/overrides/ActionBar.tsx
2253
+ import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
2254
+ var getClassName3 = get_class_name_factory_default("ActionBar", ActionBar_default);
2255
+ var ActionBarOverride = (props) => {
2256
+ const { handleBuild, canBuild } = useBuild();
2257
+ const { handleRemodel, canRemodel } = useRemodel();
2258
+ const { handleDecompose, canDecompose } = useDecompose();
2259
+ const softComponents = useSoftConfig((s) => s.softComponents);
2260
+ const status = useSoftConfig((s) => s.state);
2261
+ const isSoftComponent2 = Object.keys(softComponents || {}).includes(props.label);
2262
+ return /* @__PURE__ */ jsx9("div", { className: getClassName3(), children: /* @__PURE__ */ jsxs3(ActionBar, { children: [
2263
+ /* @__PURE__ */ jsxs3(ActionBar.Group, { children: [
2264
+ props.parentAction,
2265
+ /* @__PURE__ */ jsx9(ActionBar.Label, { label: props.label })
2266
+ ] }),
2267
+ /* @__PURE__ */ jsxs3(ActionBar.Group, { children: [
2268
+ status === "ready" ? isSoftComponent2 ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
2269
+ /* @__PURE__ */ jsx9(
2270
+ ActionBar.Action,
2271
+ {
2272
+ onClick: () => handleRemodel(props.label),
2273
+ label: "Remodel Soft Component",
2274
+ children: /* @__PURE__ */ jsx9(EditIcon, { size: 16 })
2275
+ }
2276
+ ),
2277
+ /* @__PURE__ */ jsx9(
2278
+ ActionBar.Action,
2279
+ {
2280
+ onClick: () => handleDecompose(),
2281
+ label: "Decompose Soft Component",
2282
+ children: /* @__PURE__ */ jsx9(Combine, { size: 16 })
2283
+ }
2284
+ )
2285
+ ] }) : /* @__PURE__ */ jsx9(ActionBar.Action, { onClick: handleBuild, label: "Build Soft Component", children: /* @__PURE__ */ jsx9(ComponentIcon, { size: 16 }) }) : null,
2286
+ props.children
2287
+ ] })
2288
+ ] }) });
2289
+ };
2290
+
2291
+ // src/puck/overrides/ComponentItem.tsx
2292
+ import { useState as useState5 } from "react";
2293
+ import { Button as Button2, IconButton } from "@measured/puck";
2294
+ import { GripVertical, Check, X, Trash2, Cog } from "lucide-react";
2295
+
2296
+ // src/puck/lib/confirm.ts
2297
+ var confirmHandler = (message) => {
2298
+ return window.confirm(message);
2299
+ };
2300
+ var setConfirmHandler = (handler) => {
2301
+ confirmHandler = handler;
2302
+ };
2303
+ var confirm = (message) => __async(null, null, function* () {
2304
+ try {
2305
+ const result = confirmHandler(message);
2306
+ return result instanceof Promise ? yield result : result;
2307
+ } catch (error) {
2308
+ console.error("Confirm handler error:", error);
2309
+ return false;
2310
+ }
2311
+ });
2312
+
2313
+ // src/puck/overrides/ComponentItem.module.css
2314
+ var ComponentItem_default = {};
2315
+
2316
+ // src/puck/components/modal/index.tsx
2317
+ import { useEffect as useEffect4, useState as useState4 } from "react";
2318
+ import { createPortal } from "react-dom";
2319
+
2320
+ // src/puck/components/modal/styles.module.css
2321
+ var styles_default2 = {};
2322
+
2323
+ // src/puck/components/modal/index.tsx
2324
+ import { jsx as jsx10 } from "react/jsx-runtime";
2325
+ var getClassName4 = get_class_name_factory_default("Modal", styles_default2);
2326
+ var Modal = ({
2327
+ children,
2328
+ onClose,
2329
+ isOpen
2330
+ }) => {
2331
+ const [rootEl, setRootEl] = useState4(null);
2332
+ useEffect4(() => {
2333
+ setRootEl(document.getElementById("puck-portal-root"));
2334
+ }, []);
2335
+ if (!rootEl) {
2336
+ return /* @__PURE__ */ jsx10("div", {});
2337
+ }
2338
+ return createPortal(
2339
+ /* @__PURE__ */ jsx10("div", { className: getClassName4({ isOpen }), onClick: onClose, children: /* @__PURE__ */ jsx10(
2340
+ "div",
2341
+ {
2342
+ className: getClassName4("inner"),
2343
+ onClick: (e) => e.stopPropagation(),
2344
+ children
2345
+ }
2346
+ ) }),
2347
+ rootEl
2348
+ );
2349
+ };
2350
+
2351
+ // src/puck/overrides/ComponentItem.tsx
2352
+ import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
2353
+ var getClassName5 = get_class_name_factory_default("ComponentItem", ComponentItem_default);
2354
+ var ComponentItem = (props) => {
2355
+ const softComponents = new Set(
2356
+ Object.keys(useSoftConfig((s) => s.softComponents))
2357
+ );
2358
+ const removeSoftComponentVersion = useSoftConfig(
2359
+ (s) => s.removeSoftComponentVersion
2360
+ );
2361
+ const { handleDemolish } = useDemolish();
2362
+ const { handleSetDefaultVersion, getVersions, getDefaultVersion } = useSetDefaultVersion();
2363
+ const [isEditing, setIsEditing] = useState5(false);
2364
+ const [isHovering, setIsHovering] = useState5(false);
2365
+ const [selectedVersion, setSelectedVersion] = useState5("");
2366
+ const [versionsToDelete, setVersionsToDelete] = useState5(
2367
+ /* @__PURE__ */ new Set()
2368
+ );
2369
+ const [migrateVersionMap, setMigrateVersionMap] = useState5({});
2370
+ const versions = getVersions(props.name);
2371
+ const defaultVersion = getDefaultVersion(props.name);
2372
+ const handleApply = () => __async(null, null, function* () {
2373
+ if (selectedVersion && selectedVersion !== defaultVersion) {
2374
+ handleSetDefaultVersion(props.name, selectedVersion);
2375
+ }
2376
+ if (versionsToDelete.size > 0) {
2377
+ for (const version of versionsToDelete) {
2378
+ const remaining = versions.filter((v) => !versionsToDelete.has(v));
2379
+ if (remaining.length === 0) {
2380
+ const shouldDemolish = yield confirm(
2381
+ `Deleting all versions will remove "${props.name}" entirely. Continue?`
2382
+ );
2383
+ if (shouldDemolish) {
2384
+ handleDemolish(props.name);
2385
+ }
2386
+ break;
2387
+ } else {
2388
+ removeSoftComponentVersion(props.name, version);
2389
+ }
2390
+ }
2391
+ }
2392
+ setIsEditing(false);
2393
+ setSelectedVersion("");
2394
+ setVersionsToDelete(/* @__PURE__ */ new Set());
2395
+ setMigrateVersionMap({});
2396
+ });
2397
+ const handleCancel = () => {
2398
+ setIsEditing(false);
2399
+ setSelectedVersion("");
2400
+ setVersionsToDelete(/* @__PURE__ */ new Set());
2401
+ setMigrateVersionMap({});
2402
+ };
2403
+ const toggleVersionForDeletion = (version) => {
2404
+ const newSet = new Set(versionsToDelete);
2405
+ if (newSet.has(version)) {
2406
+ newSet.delete(version);
2407
+ } else {
2408
+ newSet.add(version);
2409
+ }
2410
+ setVersionsToDelete(newSet);
2411
+ };
2412
+ const handleDemolishClick = () => __async(null, null, function* () {
2413
+ const confirmed = yield confirm(
2414
+ `Demolish "${props.name}" entirely? This will remove all versions.`
2415
+ );
2416
+ if (confirmed) {
2417
+ handleDemolish(props.name);
2418
+ setIsEditing(false);
2419
+ }
2420
+ });
2421
+ if (softComponents.has(props.name)) {
2422
+ const availableVersions = versions.filter((v) => !versionsToDelete.has(v));
2423
+ return /* @__PURE__ */ jsxs4(Fragment5, { children: [
2424
+ /* @__PURE__ */ jsxs4(
2425
+ "div",
2426
+ {
2427
+ className: getClassName5(),
2428
+ onMouseEnter: () => setIsHovering(true),
2429
+ onMouseLeave: () => setIsHovering(false),
2430
+ children: [
2431
+ /* @__PURE__ */ jsxs4("div", { className: getClassName5("content"), children: [
2432
+ /* @__PURE__ */ jsx11("div", { className: getClassName5("name"), children: props.name }),
2433
+ /* @__PURE__ */ jsxs4("div", { className: getClassName5("version"), children: [
2434
+ "v",
2435
+ defaultVersion
2436
+ ] })
2437
+ ] }),
2438
+ /* @__PURE__ */ jsxs4("div", { className: getClassName5("actions"), children: [
2439
+ isHovering && /* @__PURE__ */ jsx11("div", { className: getClassName5("settingsButton"), children: /* @__PURE__ */ jsx11(
2440
+ IconButton,
2441
+ {
2442
+ title: "Settings",
2443
+ variant: "secondary",
2444
+ onClick: (e) => {
2445
+ e.stopPropagation();
2446
+ setIsEditing(true);
2447
+ setSelectedVersion(defaultVersion || "");
2448
+ },
2449
+ children: /* @__PURE__ */ jsx11(Cog, { size: 14 })
2450
+ }
2451
+ ) }),
2452
+ /* @__PURE__ */ jsx11("div", { className: getClassName5("grip"), children: /* @__PURE__ */ jsx11(GripVertical, { size: 16 }) })
2453
+ ] })
2454
+ ]
2455
+ }
2456
+ ),
2457
+ /* @__PURE__ */ jsx11(Modal, { isOpen: isEditing, onClose: handleCancel, children: /* @__PURE__ */ jsxs4("div", { className: getClassName5("modal"), children: [
2458
+ /* @__PURE__ */ jsxs4("div", { className: getClassName5("modalHeader"), children: [
2459
+ /* @__PURE__ */ jsx11("h2", { className: getClassName5("modalTitle"), children: props.name }),
2460
+ /* @__PURE__ */ jsx11("p", { className: getClassName5("modalSubtitle"), children: "Manage versions and settings" })
2461
+ ] }),
2462
+ /* @__PURE__ */ jsxs4("div", { className: getClassName5("modalBody"), children: [
2463
+ /* @__PURE__ */ jsxs4("div", { className: getClassName5("section"), children: [
2464
+ /* @__PURE__ */ jsx11("h3", { className: getClassName5("sectionTitle"), children: "Versions" }),
2465
+ /* @__PURE__ */ jsx11("div", { className: getClassName5("versionList"), children: versions.map((version) => {
2466
+ const isDefault = version === (selectedVersion || defaultVersion);
2467
+ const isMarkedForDeletion = versionsToDelete.has(version);
2468
+ let rowClass = getClassName5("versionRow");
2469
+ if (isDefault) rowClass += " " + getClassName5("versionRow--isDefault");
2470
+ if (isMarkedForDeletion) rowClass += " " + getClassName5("versionRow--isMarkedForDeletion");
2471
+ return /* @__PURE__ */ jsxs4(
2472
+ "div",
2473
+ {
2474
+ className: rowClass,
2475
+ children: [
2476
+ /* @__PURE__ */ jsxs4("div", { className: getClassName5("versionInfo"), children: [
2477
+ /* @__PURE__ */ jsxs4("span", { className: getClassName5("versionNumber"), children: [
2478
+ "Version ",
2479
+ version
2480
+ ] }),
2481
+ isDefault && /* @__PURE__ */ jsx11("span", { className: getClassName5("defaultBadge"), children: "Default" }),
2482
+ isMarkedForDeletion && /* @__PURE__ */ jsx11("span", { className: getClassName5("deleteBadge"), children: "Marked for deletion" })
2483
+ ] }),
2484
+ /* @__PURE__ */ jsxs4("div", { className: getClassName5("versionActions"), children: [
2485
+ !isDefault && !isMarkedForDeletion && /* @__PURE__ */ jsx11(
2486
+ Button2,
2487
+ {
2488
+ variant: "secondary",
2489
+ onClick: () => setSelectedVersion(version),
2490
+ children: "Set as Default"
2491
+ }
2492
+ ),
2493
+ /* @__PURE__ */ jsx11(
2494
+ Button2,
2495
+ {
2496
+ variant: isMarkedForDeletion ? "secondary" : "secondary",
2497
+ onClick: () => toggleVersionForDeletion(version),
2498
+ children: isMarkedForDeletion ? /* @__PURE__ */ jsxs4(Fragment5, { children: [
2499
+ /* @__PURE__ */ jsx11(X, { size: 14 }),
2500
+ "Undo"
2501
+ ] }) : /* @__PURE__ */ jsxs4(Fragment5, { children: [
2502
+ /* @__PURE__ */ jsx11(Trash2, { size: 14 }),
2503
+ "Delete"
2504
+ ] })
2505
+ }
2506
+ )
2507
+ ] })
2508
+ ]
2509
+ },
2510
+ version
2511
+ );
2512
+ }) })
2513
+ ] }),
2514
+ versionsToDelete.size > 0 && availableVersions.length > 0 && /* @__PURE__ */ jsxs4("div", { className: getClassName5("section"), children: [
2515
+ /* @__PURE__ */ jsx11("h3", { className: getClassName5("sectionTitle"), children: "Migration Settings" }),
2516
+ /* @__PURE__ */ jsx11("p", { className: getClassName5("sectionDescription"), children: "Choose what to do with components using deleted versions" }),
2517
+ /* @__PURE__ */ jsx11("div", { className: getClassName5("migrationOptions"), children: /* @__PURE__ */ jsxs4(
2518
+ "select",
2519
+ {
2520
+ className: getClassName5("select"),
2521
+ value: migrateVersionMap[Array.from(versionsToDelete)[0]] || "decompose",
2522
+ onChange: (e) => {
2523
+ const newMap = __spreadValues({}, migrateVersionMap);
2524
+ versionsToDelete.forEach((v) => {
2525
+ newMap[v] = e.target.value;
2526
+ });
2527
+ setMigrateVersionMap(newMap);
2528
+ },
2529
+ children: [
2530
+ /* @__PURE__ */ jsx11("option", { value: "decompose", children: "Decompose to basic elements" }),
2531
+ availableVersions.map((v) => /* @__PURE__ */ jsxs4("option", { value: v, children: [
2532
+ "Migrate to Version ",
2533
+ v
2534
+ ] }, v))
2535
+ ]
2536
+ }
2537
+ ) })
2538
+ ] })
2539
+ ] }),
2540
+ /* @__PURE__ */ jsxs4("div", { className: getClassName5("modalFooter"), children: [
2541
+ /* @__PURE__ */ jsxs4("div", { className: getClassName5("footerLeft"), children: [
2542
+ /* @__PURE__ */ jsxs4(Button2, { size: "medium", onClick: handleApply, children: [
2543
+ /* @__PURE__ */ jsx11(Check, { size: 16 }),
2544
+ "Apply Changes"
2545
+ ] }),
2546
+ /* @__PURE__ */ jsxs4(Button2, { size: "medium", variant: "secondary", onClick: handleCancel, children: [
2547
+ /* @__PURE__ */ jsx11(X, { size: 16 }),
2548
+ "Cancel"
2549
+ ] })
2550
+ ] }),
2551
+ /* @__PURE__ */ jsx11("div", { className: getClassName5("footerRight"), children: /* @__PURE__ */ jsxs4(
2552
+ Button2,
2553
+ {
2554
+ size: "medium",
2555
+ variant: "secondary",
2556
+ onClick: handleDemolishClick,
2557
+ children: [
2558
+ /* @__PURE__ */ jsx11(Trash2, { size: 16 }),
2559
+ "Demolish Component"
2560
+ ]
2561
+ }
2562
+ ) })
2563
+ ] })
2564
+ ] }) })
2565
+ ] });
2566
+ }
2567
+ return /* @__PURE__ */ jsx11(Fragment5, { children: props.children });
2568
+ };
2569
+
2570
+ // src/puck/lib/dissolve-all-soft-components.ts
2571
+ function extractDependencies2(softComponents, componentName, version) {
2572
+ var _a, _b;
2573
+ const dependencies = /* @__PURE__ */ new Set();
2574
+ const component = (_b = (_a = softComponents[componentName]) == null ? void 0 : _a.versions) == null ? void 0 : _b[version];
2575
+ if (!component) {
2576
+ return dependencies;
2577
+ }
2578
+ const processSubComponents = (subComponents) => {
2579
+ if (!Array.isArray(subComponents)) return;
2580
+ for (const subComponent of subComponents) {
2581
+ if (subComponent == null ? void 0 : subComponent.type) {
2582
+ dependencies.add(subComponent.type);
2583
+ if (subComponent.components) {
2584
+ Object.values(subComponent.components).forEach((nestedComponents) => {
2585
+ processSubComponents(nestedComponents);
2586
+ });
2587
+ }
2588
+ }
2589
+ }
2590
+ };
2591
+ processSubComponents(component.components);
2592
+ return dependencies;
2593
+ }
2594
+ function reverseTopologicalSort(softComponents, hardComponentNames) {
2595
+ const sorted = [];
2596
+ const visiting = /* @__PURE__ */ new Set();
2597
+ const visited = /* @__PURE__ */ new Set();
2598
+ const dependencyGraph = /* @__PURE__ */ new Map();
2599
+ const dependents = /* @__PURE__ */ new Map();
2600
+ for (const [componentName, component] of Object.entries(softComponents)) {
2601
+ const defaultVersion = component.defaultVersion || Object.keys(component.versions || {}).pop();
2602
+ if (!defaultVersion) continue;
2603
+ const allDeps = extractDependencies2(
2604
+ softComponents,
2605
+ componentName,
2606
+ defaultVersion
2607
+ );
2608
+ const softDeps = new Set(
2609
+ [...allDeps].filter((dep) => !hardComponentNames.has(dep))
2610
+ );
2611
+ dependencyGraph.set(componentName, softDeps);
2612
+ for (const dep of softDeps) {
2613
+ if (!dependents.has(dep)) {
2614
+ dependents.set(dep, /* @__PURE__ */ new Set());
2615
+ }
2616
+ dependents.get(dep).add(componentName);
2617
+ }
2618
+ }
2619
+ const depths = /* @__PURE__ */ new Map();
2620
+ function calculateDepth(componentName) {
2621
+ if (depths.has(componentName)) {
2622
+ return depths.get(componentName);
2623
+ }
2624
+ const deps = dependencyGraph.get(componentName) || /* @__PURE__ */ new Set();
2625
+ if (deps.size === 0) {
2626
+ depths.set(componentName, 0);
2627
+ return 0;
2628
+ }
2629
+ let maxDepth = -1;
2630
+ for (const dep of deps) {
2631
+ if (softComponents[dep]) {
2632
+ maxDepth = Math.max(maxDepth, calculateDepth(dep));
2633
+ }
2634
+ }
2635
+ const depth = maxDepth + 1;
2636
+ depths.set(componentName, depth);
2637
+ return depth;
2638
+ }
2639
+ for (const componentName of Object.keys(softComponents)) {
2640
+ calculateDepth(componentName);
2641
+ }
2642
+ const sortedByDepth = [...depths.entries()].sort(([, depthA], [, depthB]) => depthB - depthA).map(([name]) => name);
2643
+ return sortedByDepth;
2644
+ }
2645
+ function dissolveComponentRecursively(componentData, softComponents, hardComponentNames, depth = 0) {
2646
+ const MAX_DEPTH = 50;
2647
+ if (depth > MAX_DEPTH) {
2648
+ console.error(
2649
+ `Maximum dissolution depth (${MAX_DEPTH}) exceeded for component ${componentData.type}. Possible circular dependency.`
2650
+ );
2651
+ return [componentData];
2652
+ }
2653
+ const componentType = componentData.type;
2654
+ if (!isSoftComponent(componentType, softComponents)) {
2655
+ return [dissolveComponentSlots(componentData, softComponents, hardComponentNames, depth)];
2656
+ }
2657
+ let decomposed;
2658
+ try {
2659
+ decomposed = decomposeSoftComponent(componentData, softComponents);
2660
+ } catch (error) {
2661
+ console.warn(
2662
+ `Failed to decompose soft component "${componentType}":`,
2663
+ error
2664
+ );
2665
+ return [componentData];
2666
+ }
2667
+ const fullyDissolved = [];
2668
+ for (const component of decomposed) {
2669
+ const dissolved = dissolveComponentRecursively(
2670
+ component,
2671
+ softComponents,
2672
+ hardComponentNames,
2673
+ depth + 1
2674
+ );
2675
+ fullyDissolved.push(...dissolved);
2676
+ }
2677
+ return fullyDissolved;
2678
+ }
2679
+ function dissolveComponentSlots(componentData, softComponents, hardComponentNames, depth) {
2680
+ const newProps = __spreadValues({}, componentData.props);
2681
+ Object.entries(newProps).forEach(([key, value]) => {
2682
+ var _a;
2683
+ if (Array.isArray(value) && value.length > 0 && ((_a = value[0]) == null ? void 0 : _a.type)) {
2684
+ newProps[key] = value.flatMap(
2685
+ (slotComponent) => dissolveComponentRecursively(
2686
+ slotComponent,
2687
+ softComponents,
2688
+ hardComponentNames,
2689
+ depth
2690
+ )
2691
+ );
2692
+ }
2693
+ });
2694
+ return __spreadProps(__spreadValues({}, componentData), {
2695
+ props: newProps
2696
+ });
2697
+ }
2698
+ function dissolveAllSoftComponents(data, softComponents, config) {
2699
+ const hardComponentNames = new Set(
2700
+ Object.keys(config.components || {}).filter(
2701
+ (name) => !isSoftComponent(name, softComponents)
2702
+ )
2703
+ );
2704
+ const dissolutionOrder = reverseTopologicalSort(
2705
+ softComponents,
2706
+ hardComponentNames
2707
+ );
2708
+ const dissolveComponents = (components) => {
2709
+ return components.flatMap((componentData) => {
2710
+ return dissolveComponentRecursively(
2711
+ componentData,
2712
+ softComponents,
2713
+ hardComponentNames,
2714
+ 0
2715
+ );
2716
+ });
2717
+ };
2718
+ const newContent = dissolveComponents(data.content || []);
2719
+ const newZones = {};
2720
+ if (data.zones) {
2721
+ Object.entries(data.zones).forEach(([zoneName, zoneComponents]) => {
2722
+ newZones[zoneName] = dissolveComponents(zoneComponents);
2723
+ });
2724
+ }
2725
+ const result = __spreadValues(__spreadProps(__spreadValues({}, data), {
2726
+ content: newContent
2727
+ }), data.zones && { zones: newZones });
2728
+ return result;
2729
+ }
2730
+ function validateOnlyHardComponents(data, softComponents) {
2731
+ const softComponentsFound = [];
2732
+ const checkComponents = (components) => {
2733
+ for (const component of components) {
2734
+ if (isSoftComponent(component.type, softComponents)) {
2735
+ softComponentsFound.push(component.type);
2736
+ }
2737
+ Object.values(component.props || {}).forEach((value) => {
2738
+ var _a;
2739
+ if (Array.isArray(value) && value.length > 0 && ((_a = value[0]) == null ? void 0 : _a.type)) {
2740
+ checkComponents(value);
2741
+ }
2742
+ });
2743
+ }
2744
+ };
2745
+ checkComponents(data.content || []);
2746
+ if (data.zones) {
2747
+ Object.values(data.zones).forEach((zoneComponents) => {
2748
+ checkComponents(zoneComponents);
2749
+ });
2750
+ }
2751
+ return {
2752
+ isValid: softComponentsFound.length === 0,
2753
+ softComponentsFound: [...new Set(softComponentsFound)]
2754
+ };
2755
+ }
2756
+
2757
+ // src/puck/lib/resolve-soft-config.ts
2758
+ var resolveSoftConfig = (data, softComponents, config) => {
2759
+ const dissolved = dissolveAllSoftComponents(data, softComponents, config);
2760
+ if (process.env.NODE_ENV === "development") {
2761
+ const validation = validateOnlyHardComponents(dissolved, softComponents);
2762
+ if (!validation.isValid) {
2763
+ console.warn(
2764
+ "Warning: Soft components still present after dissolution:",
2765
+ validation.softComponentsFound
2766
+ );
2767
+ }
2768
+ }
2769
+ return dissolved;
2770
+ };
2771
+ export {
2772
+ ActionBarOverride as ActionBar,
2773
+ ComponentItem,
2774
+ Header,
2775
+ SoftConfigProvider,
2776
+ confirm,
2777
+ createSoftConfigStore,
2778
+ createUseSoftConfig,
2779
+ notify,
2780
+ resolveSoftConfig,
2781
+ setConfirmHandler,
2782
+ setNotificationHandler,
2783
+ useBuild,
2784
+ useCancel,
2785
+ useComplete,
2786
+ useDecompose,
2787
+ useDemolish,
2788
+ useInspect,
2789
+ useRemodel,
2790
+ useSetDefaultVersion,
2791
+ useSoftConfig
2792
+ };