@snowcone-app/canvas 0.17.1 → 0.17.3

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.
Files changed (65) hide show
  1. package/dist/{CanvasStateV1-C6i6vU6p.js → CanvasStateV1-BG2hEc3-.js} +3 -3
  2. package/dist/{CanvasStateV1-C6i6vU6p.js.map → CanvasStateV1-BG2hEc3-.js.map} +1 -1
  3. package/dist/EditorCanvasImpl-DQxqdgpq.js +70 -0
  4. package/dist/EditorCanvasImpl-DQxqdgpq.js.map +1 -0
  5. package/dist/EditorContext-CGkfmbgo.js +1178 -0
  6. package/dist/EditorContext-CGkfmbgo.js.map +1 -0
  7. package/dist/{ElementFactory-C05JJkRp.js → ElementFactory-CuHSAPfg.js} +1469 -710
  8. package/dist/ElementFactory-CuHSAPfg.js.map +1 -0
  9. package/dist/{HybridHistoryManager-Bht98XRv.js → FontAnalyzer-CLv7_msL.js} +2104 -2903
  10. package/dist/FontAnalyzer-CLv7_msL.js.map +1 -0
  11. package/dist/{ImportManager-kRYfIX-D.js → ImportManager-C_wBjWaV.js} +147 -147
  12. package/dist/{ImportManager-kRYfIX-D.js.map → ImportManager-C_wBjWaV.js.map} +1 -1
  13. package/dist/SnowconeCanvas-DBbmx9qW.js +1187 -0
  14. package/dist/SnowconeCanvas-DBbmx9qW.js.map +1 -0
  15. package/dist/{UnifiedFontService-BAtqqkU4.js → UnifiedFontService-Dsu5cwfT.js} +141 -141
  16. package/dist/UnifiedFontService-Dsu5cwfT.js.map +1 -0
  17. package/dist/advanced.mjs +10 -10
  18. package/dist/components/editor/RootInternals.d.ts +7 -0
  19. package/dist/components/embed/EmbedRoot.d.ts +23 -0
  20. package/dist/components/embed/SnowconeCanvas.d.ts +13 -0
  21. package/dist/components/embed/kernel.d.ts +114 -0
  22. package/dist/contexts/BoundLayerGuardContext.d.ts +36 -0
  23. package/dist/core/GroupElement.d.ts +0 -5
  24. package/dist/core/TextElement.d.ts +8 -3
  25. package/dist/core/paint-registry.d.ts +42 -0
  26. package/dist/core/rich-text-layout.d.ts +28 -0
  27. package/dist/{editorErrors-DbIEtCTt.js → editorErrors-BY4Pdg7a.js} +2 -2
  28. package/dist/{editorErrors-DbIEtCTt.js.map → editorErrors-BY4Pdg7a.js.map} +1 -1
  29. package/dist/{embed-B5kewSQY.js → embed--B8ot6Lj.js} +207 -199
  30. package/dist/embed--B8ot6Lj.js.map +1 -0
  31. package/dist/embed.mjs +21 -22
  32. package/dist/embed.mjs.map +1 -1
  33. package/dist/index.mjs +7 -7
  34. package/dist/internals.mjs +93 -93
  35. package/dist/rendering/element-painters.d.ts +16 -0
  36. package/dist/rendering/rich-text-renderer.d.ts +3 -28
  37. package/dist/{template-fields-GOM4MNfq.js → template-fields-Z9x13sjM.js} +32 -33
  38. package/dist/{template-fields-GOM4MNfq.js.map → template-fields-Z9x13sjM.js.map} +1 -1
  39. package/dist/testing.mjs +7 -7
  40. package/dist/transforms/ArchTransform.d.ts +0 -1
  41. package/dist/transforms/AscendTransform.d.ts +0 -1
  42. package/dist/transforms/CircleTransform.d.ts +0 -1
  43. package/dist/transforms/FlagTransform.d.ts +0 -1
  44. package/dist/transforms/LeanTransform.d.ts +0 -1
  45. package/dist/transforms/WaveTransform.d.ts +0 -1
  46. package/dist/{usePieceGuideBundle-CGERAQJl.js → usePieceGuideBundle-C1ipFnZd.js} +2 -2
  47. package/dist/{usePieceGuideBundle-CGERAQJl.js.map → usePieceGuideBundle-C1ipFnZd.js.map} +1 -1
  48. package/dist/{validation-DEd6EOCP.js → validation-C795COGQ.js} +4803 -4791
  49. package/dist/validation-C795COGQ.js.map +1 -0
  50. package/dist/vendor/ui/primitives/kbd.d.ts +1 -1
  51. package/dist/workers/export-worker.bundle.string.d.ts +1 -1
  52. package/package.json +1 -1
  53. package/dist/EditorCanvasImpl-C8SsT3C2.js +0 -68
  54. package/dist/EditorCanvasImpl-C8SsT3C2.js.map +0 -1
  55. package/dist/EditorContext-CyanYzo2.js +0 -1131
  56. package/dist/EditorContext-CyanYzo2.js.map +0 -1
  57. package/dist/ElementFactory-C05JJkRp.js.map +0 -1
  58. package/dist/HybridHistoryManager-Bht98XRv.js.map +0 -1
  59. package/dist/SnowconeCanvas-C3eZ9PP8.js +0 -1047
  60. package/dist/SnowconeCanvas-C3eZ9PP8.js.map +0 -1
  61. package/dist/UnifiedFontService-BAtqqkU4.js.map +0 -1
  62. package/dist/editorError-DMENTZ-3.js +0 -19
  63. package/dist/editorError-DMENTZ-3.js.map +0 -1
  64. package/dist/embed-B5kewSQY.js.map +0 -1
  65. package/dist/validation-DEd6EOCP.js.map +0 -1
@@ -1,16 +1,15 @@
1
- import { C as Ee, e as Re } from "./UnifiedFontService-BAtqqkU4.js";
2
- import { y as x } from "./HybridHistoryManager-Bht98XRv.js";
1
+ import { C as Ee, e as Re } from "./UnifiedFontService-Dsu5cwfT.js";
2
+ import { y as x } from "./FontAnalyzer-CLv7_msL.js";
3
3
  import { jsx as f, jsxs as Q, Fragment as we } from "react/jsx-runtime";
4
- import { useContext as Z, createContext as ee, useRef as T, useState as O, useMemo as I, useEffect as $, useSyncExternalStore as A, Component as xe, forwardRef as te, useId as ne, useLayoutEffect as re, useCallback as se } from "react";
4
+ import { useContext as Z, createContext as ee, useRef as N, useState as O, useMemo as I, useEffect as $, useSyncExternalStore as L, Component as xe, forwardRef as te, useId as re, useLayoutEffect as ne, useCallback as se } from "react";
5
5
  import { assertVariantSelected as ie, RenderSession as Se, createCartDetail as Ie } from "@snowcone-app/sdk";
6
- import { u as Ce, p as Ne } from "./usePieceGuideBundle-CGERAQJl.js";
7
- import { E as R, i as Te, a as ae } from "./editorError-DMENTZ-3.js";
8
- import { r as oe } from "./editorErrors-DbIEtCTt.js";
9
- import { l as X, i as Oe, s as le } from "./template-fields-GOM4MNfq.js";
10
- import "./EditorContext-CyanYzo2.js";
11
- import "./CanvasStateV1-C6i6vU6p.js";
6
+ import { g as R, i as Ce, h as ae, B as Te, E as Ne } from "./EditorContext-CGkfmbgo.js";
7
+ import { u as Oe, p as ke } from "./usePieceGuideBundle-C1ipFnZd.js";
8
+ import { r as oe } from "./editorErrors-BY4Pdg7a.js";
9
+ import { l as X, i as _e, s as le } from "./template-fields-Z9x13sjM.js";
10
+ import "./CanvasStateV1-BG2hEc3-.js";
12
11
  const de = ee(void 0);
13
- function L() {
12
+ function A() {
14
13
  const t = Z(de);
15
14
  if (!t)
16
15
  throw new Error(
@@ -18,42 +17,42 @@ function L() {
18
17
  );
19
18
  return t;
20
19
  }
21
- const ke = "[RealtimeEmbed]";
22
- function _e(t) {
23
- var r, s;
24
- if ((r = t == null ? void 0 : t.requiredPlacements) != null && r.length)
20
+ const $e = "[RealtimeEmbed]";
21
+ function Be(t) {
22
+ var n, s;
23
+ if ((n = t == null ? void 0 : t.requiredPlacements) != null && n.length)
25
24
  return t.requiredPlacements.filter((a) => !a.autoFilledByVariant).map((a) => a.label);
26
25
  const e = new Set(
27
26
  (((s = t == null ? void 0 : t.options) == null ? void 0 : s.combinations) ?? []).map((a) => a.variantId).filter((a) => typeof a == "string" && a !== "")
28
27
  );
29
28
  return !!(t != null && t.variantId) || e.size > 1 ? [] : (t == null ? void 0 : t.placements) ?? [];
30
29
  }
31
- function ue({ shop: t, product: e, design: n, hasGrant: r }) {
32
- var m, d;
30
+ function ue({ shop: t, product: e, design: r, hasGrant: n }) {
31
+ var c, d;
33
32
  const s = [];
34
33
  if (t || s.push({
35
34
  severity: "error",
36
35
  issue: "missing-shop",
37
36
  message: "`shop` is required (your publishable shop id)."
38
- }), r || s.push({
37
+ }), n || s.push({
39
38
  severity: "error",
40
39
  issue: "missing-grant",
41
40
  message: "no grant source — pass `grantUrl` (a proxy to mintRealtimeGrant) or `grant`. Without it the session can never authorize and no mockup renders."
42
- }), (m = e == null ? void 0 : e.mockupIds) != null && m.length || s.push({
41
+ }), (c = e == null ? void 0 : e.mockupIds) != null && c.length || s.push({
43
42
  severity: "error",
44
43
  issue: "empty-mockup-ids",
45
44
  message: 'product.mockupIds is empty — pass the catalog scene codes (product.mockups[].id) you want rendered, e.g. ["FV1qjO"].'
46
45
  }), e != null && e.options)
47
46
  try {
48
47
  ie(e);
49
- } catch (c) {
48
+ } catch (m) {
50
49
  s.push({
51
50
  severity: "error",
52
51
  issue: "variant-required",
53
- message: c instanceof Error ? c.message : String(c)
52
+ message: m instanceof Error ? m.message : String(m)
54
53
  });
55
54
  }
56
- const a = n.toJSON(), l = a.activeArtboard, i = _e(e);
55
+ const a = r.toJSON(), l = a.activeArtboard, i = Be(e);
57
56
  i.length > 1 && s.push({
58
57
  severity: "error",
59
58
  issue: "multi-placement",
@@ -63,16 +62,16 @@ function ue({ shop: t, product: e, design: n, hasGrant: r }) {
63
62
  issue: "placement-mismatch",
64
63
  message: `the design's placement "${l}" is not in product.placements [${e.placements.join(", ")}]. The canvas artboard name and renderState placement must equal a real product placement label, or the server renders a blank mockup. Fix the \`name\` passed to design({ name }).`
65
64
  });
66
- const o = a.elements.map((c) => c.name).filter((c) => !!c), u = o.filter((c, y) => o.indexOf(c) !== y);
65
+ const o = a.elements.map((m) => m.name).filter((m) => !!m), u = o.filter((m, y) => o.indexOf(m) !== y);
67
66
  return u.length && s.push({
68
67
  severity: "warn",
69
68
  issue: "duplicate-layer-names",
70
69
  message: `duplicate layer name(s) [${[...new Set(u)].join(", ")}] — useTextBinding(name) / useImageBinding(name) bind to the FIRST match, so a duplicate name makes a control edit the wrong layer. Keep names unique.`
71
70
  }), s;
72
71
  }
73
- function $e(t) {
72
+ function Fe(t) {
74
73
  for (const e of ue(t))
75
- (e.severity === "error" && e.issue !== "placement-mismatch" ? console.error : console.warn)(`${ke} ${e.message}`);
74
+ (e.severity === "error" && e.issue !== "placement-mismatch" ? console.error : console.warn)(`${$e} ${e.message}`);
76
75
  }
77
76
  function j(t) {
78
77
  return t.text;
@@ -80,15 +79,15 @@ function j(t) {
80
79
  function _(t) {
81
80
  return t.name;
82
81
  }
83
- class Be {
82
+ class De {
84
83
  constructor(e) {
85
- this.listeners = /* @__PURE__ */ new Set(), this.getState = () => this.state, this.subscribe = (r) => (this.listeners.add(r), () => this.listeners.delete(r)), this.state = e;
86
- const n = /* @__PURE__ */ new Map();
87
- for (const r of e.elements) {
88
- const s = _(r), a = j(r);
89
- s && typeof a == "string" && n.set(s, a);
84
+ this.listeners = /* @__PURE__ */ new Set(), this.getState = () => this.state, this.subscribe = (n) => (this.listeners.add(n), () => this.listeners.delete(n)), this.state = e;
85
+ const r = /* @__PURE__ */ new Map();
86
+ for (const n of e.elements) {
87
+ const s = _(n), a = j(n);
88
+ s && typeof a == "string" && r.set(s, a);
90
89
  }
91
- this.seedTextByName = n;
90
+ this.seedTextByName = r;
92
91
  }
93
92
  /** Replace the whole state (the canvas `onChange` path). */
94
93
  setState(e) {
@@ -100,14 +99,14 @@ class Be {
100
99
  }
101
100
  /** Current text of a named text layer, or undefined when absent. */
102
101
  textOf(e) {
103
- const n = this.state.elements.find((r) => _(r) === e);
104
- return n ? j(n) : void 0;
102
+ const r = this.state.elements.find((n) => _(n) === e);
103
+ return r ? j(r) : void 0;
105
104
  }
106
105
  /** Kind of the named layer in the CURRENT state ('text' | 'image' | null
107
106
  * for unbindable), or undefined when no layer has the name. */
108
107
  layerKindOf(e) {
109
- const n = this.state.elements.find((r) => _(r) === e);
110
- return n ? X(n) : void 0;
108
+ const r = this.state.elements.find((n) => _(n) === e);
109
+ return r ? X(r) : void 0;
111
110
  }
112
111
  /** Names of bindable layers in the current state, for error messages. */
113
112
  bindableLayerNames() {
@@ -118,10 +117,10 @@ class Be {
118
117
  * one, writes route through the editor command path and arrive back here
119
118
  * via `setState`). Immutable update; last-write-wins.
120
119
  */
121
- updateTextLayer(e, n) {
122
- let r = !1;
123
- const s = this.state.elements.map((a) => _(a) !== e ? a : (r = !0, { ...a, text: n }));
124
- if (!r)
120
+ updateTextLayer(e, r) {
121
+ let n = !1;
122
+ const s = this.state.elements.map((a) => _(a) !== e ? a : (n = !0, { ...a, text: r }));
123
+ if (!n)
125
124
  throw new R(
126
125
  "E_LAYER_NOT_FOUND",
127
126
  `no layer "${e}" in the current design state. Bindable layers: ${JSON.stringify(this.bindableLayerNames())}.`,
@@ -134,18 +133,18 @@ class Be {
134
133
  hasRenderableElement() {
135
134
  return this.state.elements.some((e) => {
136
135
  if (e.visible === !1) return !1;
137
- const n = e.transformType;
138
- if (n === "image") return !!e.imageUrl;
139
- if (n === "shape" || n === "group" || n === "path") return !0;
140
- const r = j(e);
141
- return typeof r == "string" && r.trim().length > 0;
136
+ const r = e.transformType;
137
+ if (r === "image") return !!e.imageUrl;
138
+ if (r === "shape" || r === "group" || r === "path") return !0;
139
+ const n = j(e);
140
+ return typeof n == "string" && n.trim().length > 0;
142
141
  });
143
142
  }
144
143
  emit() {
145
144
  for (const e of [...this.listeners]) e();
146
145
  }
147
146
  }
148
- class De {
147
+ class Ue {
149
148
  constructor() {
150
149
  this.canvasIds = /* @__PURE__ */ new Set(), this.requirements = /* @__PURE__ */ new Map(), this.textFields = /* @__PURE__ */ new Map(), this.bridge = null, this.listeners = /* @__PURE__ */ new Set(), this.version = 0, this.getVersion = () => this.version, this.subscribe = (e) => (this.listeners.add(e), () => this.listeners.delete(e));
151
150
  }
@@ -159,8 +158,8 @@ class De {
159
158
  }
160
159
  /** Declare that a part is meaningless without a mounted Canvas (ADR-0085 §4
161
160
  * table). Validated by Root once per commit. */
162
- requireCanvas(e, n) {
163
- return this.requirements.set(e, n), this.bump(), () => {
161
+ requireCanvas(e, r) {
162
+ return this.requirements.set(e, r), this.bump(), () => {
164
163
  this.requirements.delete(e), this.bump();
165
164
  };
166
165
  }
@@ -183,8 +182,8 @@ class De {
183
182
  );
184
183
  }
185
184
  }
186
- registerTextField(e, n) {
187
- return this.textFields.set(e, n), this.bump(), () => {
185
+ registerTextField(e, r) {
186
+ return this.textFields.set(e, r), this.bump(), () => {
188
187
  this.textFields.delete(e), this.bump();
189
188
  };
190
189
  }
@@ -193,6 +192,15 @@ class De {
193
192
  getTextFields() {
194
193
  return [...this.textFields.values()];
195
194
  }
195
+ /** Bound-layer lookup for the mutation guard (ADR-0085 §3 /
196
+ * `E_BOUND_LAYER_MUTATION`): a layer is bound while ANY mounted
197
+ * `Editor.TextField` carries its name. Satisfies `BoundLayerGuard`
198
+ * structurally (subscribe/getVersion above). */
199
+ getBoundLayer(e) {
200
+ for (const r of this.textFields.values())
201
+ if (r.name === e) return { part: "Editor.TextField" };
202
+ return null;
203
+ }
196
204
  registerCanvasBridge(e) {
197
205
  return this.bridge = e, this.bump(), () => {
198
206
  this.bridge === e && (this.bridge = null), this.bump();
@@ -207,7 +215,7 @@ class De {
207
215
  }
208
216
  }
209
217
  const ce = ee(null);
210
- function G(t) {
218
+ function K(t) {
211
219
  const e = Z(ce);
212
220
  if (!e)
213
221
  throw new R(
@@ -217,10 +225,10 @@ function G(t) {
217
225
  );
218
226
  return e;
219
227
  }
220
- function Fe(t) {
228
+ function Le(t) {
221
229
  return {
222
230
  reportInvariant(e) {
223
- if (Te()) throw e;
231
+ if (Ce()) throw e;
224
232
  t(e);
225
233
  },
226
234
  reportRuntimeError(e) {
@@ -229,17 +237,17 @@ function Fe(t) {
229
237
  };
230
238
  }
231
239
  const me = 8e3;
232
- function Ue(t) {
240
+ function Ae(t) {
233
241
  return `[RealtimeEmbed] No mockup after ${Math.round(me / 1e3)}s. Common causes: a variant product missing \`variantId\` (pass \`product.options\` so the embed can flag it up front), a multi-placement product (the server waits for every required placement but <RealtimeEmbed> sends only "${t}" — pass \`product.requiredPlacements\` so this is flagged at mount; such products need the eject path), an unreachable or non-public asset URL in the design, or the placement "${t}" not existing on the product. The render may still arrive — this is a heads-up, not a failure.`;
234
242
  }
235
- function Ae(t) {
243
+ function qe(t) {
236
244
  if ("grantUrl" in t && t.grantUrl)
237
245
  return { grantUrl: t.grantUrl };
238
246
  const e = t.grant;
239
247
  return typeof e == "function" ? { getToken: e } : { getToken: () => Promise.resolve(e) };
240
248
  }
241
249
  function fe({ error: t, onRetry: e }) {
242
- const n = ae(t) ? t.code : "EDITOR_ERROR";
250
+ const r = ae(t) ? t.code : "EDITOR_ERROR";
243
251
  return /* @__PURE__ */ Q(
244
252
  "div",
245
253
  {
@@ -258,7 +266,7 @@ function fe({ error: t, onRetry: e }) {
258
266
  children: [
259
267
  /* @__PURE__ */ Q("p", { style: { margin: 0, fontWeight: 700 }, children: [
260
268
  "Editor failed: ",
261
- n
269
+ r
262
270
  ] }),
263
271
  /* @__PURE__ */ f("p", { style: { margin: "4px 0 0" }, children: t.message }),
264
272
  e ? /* @__PURE__ */ f(
@@ -285,7 +293,7 @@ function fe({ error: t, onRetry: e }) {
285
293
  }
286
294
  );
287
295
  }
288
- class Le extends xe {
296
+ class Me extends xe {
289
297
  constructor() {
290
298
  super(...arguments), this.state = { caught: null };
291
299
  }
@@ -293,44 +301,44 @@ class Le extends xe {
293
301
  return { caught: e };
294
302
  }
295
303
  componentDidCatch(e) {
296
- var n;
297
- oe(e), typeof x < "u" && ((n = x.env) == null ? void 0 : n.NODE_ENV) !== "production" && console.error("[Editor.Root] contained a composition error:", e);
304
+ var r;
305
+ oe(e), typeof x < "u" && ((r = x.env) == null ? void 0 : r.NODE_ENV) !== "production" && console.error("[Editor.Root] contained a composition error:", e);
298
306
  }
299
307
  render() {
300
308
  return this.state.caught ? /* @__PURE__ */ f(fe, { error: this.state.caught }) : this.props.children;
301
309
  }
302
310
  }
303
- function qe({ reportedError: t, onRetry: e, children: n }) {
311
+ function Ve({ reportedError: t, onRetry: e, children: r }) {
304
312
  if (t) {
305
- const r = ae(t) && t.code === "E_CHUNK_LOAD_FAILED";
306
- return /* @__PURE__ */ f(fe, { error: t, onRetry: r ? e : void 0 });
313
+ const n = ae(t) && t.code === "E_CHUNK_LOAD_FAILED";
314
+ return /* @__PURE__ */ f(fe, { error: t, onRetry: n ? e : void 0 });
307
315
  }
308
- return /* @__PURE__ */ f(Le, { reportedError: null, onRetry: e, children: n });
316
+ return /* @__PURE__ */ f(Me, { reportedError: null, onRetry: e, children: r });
309
317
  }
310
- function Me(t) {
318
+ function Pe(t) {
311
319
  const {
312
320
  shop: e,
313
- product: n,
314
- design: r,
321
+ product: r,
322
+ design: n,
315
323
  throttleMs: s = 200,
316
324
  onMockups: a,
317
325
  onRenderError: l,
318
326
  wsUrl: i,
319
327
  services: o,
320
328
  children: u,
321
- internals: m,
329
+ internals: c,
322
330
  __validation: d = "throw"
323
- } = t, c = I(() => r.toJSON().activeArtboard, [r]), y = Ce(n.variantId ?? n.defaultGvid), g = I(() => {
331
+ } = t, m = I(() => n.toJSON().activeArtboard, [n]), y = Oe(r.variantId ?? r.defaultGvid), g = I(() => {
324
332
  if (!y) return null;
325
- const h = r.toJSON().artboards[0];
326
- return Ne(y, h) ?? null;
327
- }, [y, r]), b = T(a), p = T(l);
333
+ const h = n.toJSON().artboards[0];
334
+ return ke(y, h) ?? null;
335
+ }, [y, n]), b = N(a), p = N(l);
328
336
  b.current = a, p.current = l;
329
- const [S, q] = O([]), [C, N] = O(!0), [H, B] = O(null), M = !!("grantUrl" in t && t.grantUrl || "grant" in t && t.grant), V = Ae(t), ye = "grantUrl" in V ? V.grantUrl : "getToken", W = `${n.productId}|${n.mockupIds.join(",")}|${n.variantId ?? ""}`, D = `${e}|${W}|${c}|${M}`;
337
+ const [S, q] = O([]), [C, T] = O(!0), [H, B] = O(null), M = !!("grantUrl" in t && t.grantUrl || "grant" in t && t.grant), V = qe(t), ye = "grantUrl" in V ? V.grantUrl : "getToken", W = `${r.productId}|${r.mockupIds.join(",")}|${r.variantId ?? ""}`, F = `${e}|${W}|${m}|${M}`;
330
338
  I(() => {
331
339
  var E;
332
340
  if (d !== "throw") return;
333
- const h = ue({ shop: e, product: n, design: r, hasGrant: M }), v = h.find((k) => k.severity === "error");
341
+ const h = ue({ shop: e, product: r, design: n, hasGrant: M }), v = h.find((k) => k.severity === "error");
334
342
  if (v)
335
343
  throw new R("E_EMBED_CONFIG", v.message, {
336
344
  issue: v.issue,
@@ -338,116 +346,116 @@ function Me(t) {
338
346
  });
339
347
  for (const k of h)
340
348
  typeof x < "u" && ((E = x.env) == null ? void 0 : E.NODE_ENV) !== "production" && console.warn(`[Editor.Root] ${k.message}`);
341
- }, [D, d]);
342
- const z = T(null);
349
+ }, [F, d]);
350
+ const z = N(null);
343
351
  $(() => {
344
352
  var h;
345
353
  if (d === "warn" && typeof x < "u" && ((h = x.env) == null ? void 0 : h.NODE_ENV) !== "production") {
346
- if (z.current === D) return;
347
- z.current = D, $e({ shop: e, product: n, design: r, hasGrant: M });
354
+ if (z.current === F) return;
355
+ z.current = F, Fe({ shop: e, product: r, design: n, hasGrant: M });
348
356
  }
349
- }, [D, d]);
350
- const F = I(
357
+ }, [F, d]);
358
+ const D = I(
351
359
  () => {
352
360
  try {
353
- return { session: new Se({ shop: e, product: n, wsUrl: i, ...V }) };
361
+ return { session: new Se({ shop: e, product: r, wsUrl: i, ...V }) };
354
362
  } catch (h) {
355
363
  return { error: h instanceof Error ? h.message : String(h) };
356
364
  }
357
365
  },
358
366
  // eslint-disable-next-line react-hooks/exhaustive-deps
359
- [e, W, c, i, ye]
360
- ), w = "session" in F ? F.session : null, U = "error" in F ? F.error : null, P = I(() => (h, v = s) => {
361
- w && (B(null), N(!0), w.renderState(c, h, v).catch((E) => {
367
+ [e, W, m, i, ye]
368
+ ), w = "session" in D ? D.session : null, U = "error" in D ? D.error : null, P = I(() => (h, v = s) => {
369
+ w && (B(null), T(!0), w.renderState(m, h, v).catch((E) => {
362
370
  var Y;
363
371
  const k = E instanceof Error ? E.message : String(E);
364
- B(k), N(!1), (Y = p.current) == null || Y.call(p, k);
372
+ B(k), T(!1), (Y = p.current) == null || Y.call(p, k);
365
373
  }));
366
- }, [w, c, s]);
374
+ }, [w, m, s]);
367
375
  $(() => {
368
376
  var h;
369
377
  if (U) {
370
- B(U), N(!1), (h = p.current) == null || h.call(p, U);
378
+ B(U), T(!1), (h = p.current) == null || h.call(p, U);
371
379
  return;
372
380
  }
373
381
  if (w)
374
382
  return w.onMockups((v) => {
375
383
  var E;
376
- q(v), N(!1), (E = b.current) == null || E.call(b, v);
384
+ q(v), T(!1), (E = b.current) == null || E.call(b, v);
377
385
  }), w.onError((v) => {
378
386
  var E;
379
- B(v), N(!1), (E = p.current) == null || E.call(p, v);
380
- }), P(r.toServerRequest()), () => w.close();
387
+ B(v), T(!1), (E = p.current) == null || E.call(p, v);
388
+ }), P(n.toServerRequest()), () => w.close();
381
389
  }, [w, U]), $(() => {
382
390
  var v;
383
391
  if (!C || typeof x > "u" || ((v = x.env) == null ? void 0 : v.NODE_ENV) === "production") return;
384
- const h = setTimeout(() => console.warn(Ue(c)), me);
392
+ const h = setTimeout(() => console.warn(Ae(m)), me);
385
393
  return () => clearTimeout(h);
386
- }, [C, c]);
394
+ }, [C, m]);
387
395
  const ve = I(
388
396
  () => ({
389
397
  session: w,
390
- design: r,
391
- placement: c,
392
- product: n,
398
+ design: n,
399
+ placement: m,
400
+ product: r,
393
401
  mockups: S,
394
402
  isRendering: C,
395
403
  error: H,
396
404
  throttleMs: s,
397
405
  pieceGuides: g,
398
406
  pushRender: P,
399
- stateStore: m.store
407
+ stateStore: c.store
400
408
  }),
401
- [w, r, c, n, S, C, H, s, g, P, m.store]
402
- ), be = A(
403
- m.registry.subscribe,
404
- m.registry.getVersion,
405
- m.registry.getVersion
409
+ [w, n, m, r, S, C, H, s, g, P, c.store]
410
+ ), be = L(
411
+ c.registry.subscribe,
412
+ c.registry.getVersion,
413
+ c.registry.getVersion
406
414
  );
407
- I(() => m.registry.validate(), [m.registry, be]);
408
- const J = /* @__PURE__ */ f(ce.Provider, { value: m, children: /* @__PURE__ */ f(de.Provider, { value: ve, children: u }) });
415
+ I(() => c.registry.validate(), [c.registry, be]);
416
+ const J = /* @__PURE__ */ f(ce.Provider, { value: c, children: /* @__PURE__ */ f(de.Provider, { value: ve, children: /* @__PURE__ */ f(Te.Provider, { value: c.registry, children: /* @__PURE__ */ f(Ne, { children: u }) }) }) });
409
417
  return o ? /* @__PURE__ */ f(Ee, { services: o, children: J }) : J;
410
418
  }
411
419
  function he(t) {
412
- const { design: e } = t, n = T(null), [r, s] = O(null);
413
- (n.current === null || n.current.design !== e) && (n.current = {
420
+ const { design: e } = t, r = N(null), [n, s] = O(null);
421
+ (r.current === null || r.current.design !== e) && (r.current = {
414
422
  design: e,
415
423
  internals: {
416
- store: new Be(e.toJSON()),
417
- registry: new De()
424
+ store: new De(e.toJSON()),
425
+ registry: new Ue()
418
426
  }
419
427
  });
420
428
  const a = I(
421
429
  () => ({
422
- ...n.current.internals,
423
- ...Fe(s)
430
+ ...r.current.internals,
431
+ ...Le(s)
424
432
  }),
425
433
  // eslint-disable-next-line react-hooks/exhaustive-deps
426
- [n.current.internals]
434
+ [r.current.internals]
427
435
  );
428
436
  return (
429
437
  // `display: contents` — the .sc-root scope without a layout box, so the
430
438
  // host's grid/flex sees the parts directly (and the legacy RealtimeEmbed
431
439
  // wrapper, which had no DOM at all, stays layout-identical).
432
- /* @__PURE__ */ f("div", { className: "sc-root", style: { display: "contents" }, "data-sc-part": "root", children: /* @__PURE__ */ f(qe, { reportedError: r, onRetry: () => s(null), children: /* @__PURE__ */ f(Me, { ...t, internals: a }) }) })
440
+ /* @__PURE__ */ f("div", { className: "sc-root", style: { display: "contents" }, "data-sc-part": "root", children: /* @__PURE__ */ f(Ve, { reportedError: n, onRetry: () => s(null), children: /* @__PURE__ */ f(Pe, { ...t, internals: a }) }) })
433
441
  );
434
442
  }
435
- let Ve = () => import("./EditorCanvasImpl-C8SsT3C2.js").then((t) => t.EditorCanvasImpl);
443
+ let je = () => import("./EditorCanvasImpl-DQxqdgpq.js").then((t) => t.EditorCanvasImpl);
436
444
  function ge() {
437
- return Ve();
445
+ return je();
438
446
  }
439
- const Pe = te(function({ children: e, maxHeight: n, className: r, style: s }, a) {
440
- const l = G("Editor.Canvas"), i = ne();
441
- re(() => l.registry.registerCanvas(i), [l.registry, i]);
447
+ const Ge = te(function({ children: e, maxHeight: r, className: n, style: s }, a) {
448
+ const l = K("Editor.Canvas"), i = re();
449
+ ne(() => l.registry.registerCanvas(i), [l.registry, i]);
442
450
  const [o, u] = O(null);
443
451
  return $(() => {
444
- let m = !1;
452
+ let c = !1;
445
453
  return ge().then(
446
454
  (d) => {
447
- m || u(() => d);
455
+ c || u(() => d);
448
456
  },
449
457
  (d) => {
450
- m || l.reportRuntimeError(
458
+ c || l.reportRuntimeError(
451
459
  new R(
452
460
  "E_CHUNK_LOAD_FAILED",
453
461
  `the editor's rendering chunk failed to load (${d instanceof Error ? d.message : String(d)}). This is a network/CDN failure, not a composition mistake — retry, or check the deployment serves the @snowcone-app/canvas lazy chunks.`,
@@ -456,45 +464,45 @@ const Pe = te(function({ children: e, maxHeight: n, className: r, style: s }, a)
456
464
  );
457
465
  }
458
466
  ), () => {
459
- m = !0;
467
+ c = !0;
460
468
  };
461
- }, [l]), o ? /* @__PURE__ */ f(o, { ref: a, kit: "embed-only", partAttr: "canvas", maxHeight: n, className: r, style: s, children: e }) : /* @__PURE__ */ f(
469
+ }, [l]), o ? /* @__PURE__ */ f(o, { ref: a, kit: "embed-only", partAttr: "canvas", maxHeight: r, className: n, style: s, children: e }) : /* @__PURE__ */ f(
462
470
  "div",
463
471
  {
464
472
  "data-sc-part": "canvas",
465
473
  "data-sc-state": "loading",
466
- className: r,
467
- style: { minHeight: n ?? 200, ...s },
474
+ className: n,
475
+ style: { minHeight: r ?? 200, ...s },
468
476
  "aria-busy": "true"
469
477
  }
470
478
  );
471
- }), je = 1.2, K = [1200, 1400, 1600, 1800, 2e3, 2500, 3e3, 4e3];
472
- function Ke(t) {
473
- for (const e of K)
479
+ }), Ke = 1.2, G = [1200, 1400, 1600, 1800, 2e3, 2500, 3e3, 4e3];
480
+ function He(t) {
481
+ for (const e of G)
474
482
  if (e >= t) return e;
475
- return K[K.length - 1];
483
+ return G[G.length - 1];
476
484
  }
477
- function Ge(t, e) {
478
- if (!(t > 0) || !(e > 0) || e <= t * je) return null;
479
- const n = Ke(e);
480
- return `[RealtimeMockup] mockup rendered at ${t}px but displayed at ~${e} device px — the preview will look soft. Pass \`product.width\` (e.g. ${n}) on the embed for a crisp preview.`;
485
+ function We(t, e) {
486
+ if (!(t > 0) || !(e > 0) || e <= t * Ke) return null;
487
+ const r = He(e);
488
+ return `[RealtimeMockup] mockup rendered at ${t}px but displayed at ~${e} device px — the preview will look soft. Pass \`product.width\` (e.g. ${r}) on the embed for a crisp preview.`;
481
489
  }
482
490
  function pe({
483
491
  mockupId: t,
484
492
  fallback: e = null,
485
- alt: n = "Live product mockup",
486
- className: r,
493
+ alt: r = "Live product mockup",
494
+ className: n,
487
495
  style: s
488
496
  }) {
489
- const { mockups: a } = L(), l = T(/* @__PURE__ */ new Set()), i = t ? a.find((u) => u.mockupId === t && u.imageUrl) : a.find((u) => u.imageUrl);
497
+ const { mockups: a } = A(), l = N(/* @__PURE__ */ new Set()), i = t ? a.find((u) => u.mockupId === t && u.imageUrl) : a.find((u) => u.imageUrl);
490
498
  if (!(i != null && i.imageUrl))
491
499
  return /* @__PURE__ */ f(we, { children: e });
492
500
  const o = (u) => {
493
501
  var g;
494
502
  if (typeof x > "u" || ((g = x.env) == null ? void 0 : g.NODE_ENV) === "production" || typeof window > "u" || l.current.has(i.mockupId)) return;
495
- const m = u.currentTarget, d = m.getBoundingClientRect().width;
503
+ const c = u.currentTarget, d = c.getBoundingClientRect().width;
496
504
  if (d <= 0) return;
497
- const c = Math.round(d * (window.devicePixelRatio || 1)), y = Ge(m.naturalWidth, c);
505
+ const m = Math.round(d * (window.devicePixelRatio || 1)), y = We(c.naturalWidth, m);
498
506
  y && (l.current.add(i.mockupId), console.warn(y));
499
507
  };
500
508
  return (
@@ -504,17 +512,17 @@ function pe({
504
512
  {
505
513
  "data-sc-part": "preview",
506
514
  src: i.imageUrl,
507
- alt: n,
508
- className: r,
515
+ alt: r,
516
+ className: n,
509
517
  style: s,
510
518
  onLoad: o
511
519
  }
512
520
  )
513
521
  );
514
522
  }
515
- function He(t) {
516
- const { layer: e, optional: n = !1, placeholder: r, className: s, style: a } = t, l = G("Editor.TextField"), { pushRender: i, throttleMs: o, stateStore: u } = L(), m = ne(), d = T(null);
517
- if (!Oe(e))
523
+ function ze(t) {
524
+ const { layer: e, optional: r = !1, placeholder: n, className: s, style: a } = t, l = K("Editor.TextField"), { pushRender: i, throttleMs: o, stateStore: u } = A(), c = re(), d = N(null);
525
+ if (!_e(e))
518
526
  throw new R(
519
527
  "E_LAYER_TOKEN_REQUIRED",
520
528
  `the \`layer\` prop must be a token minted by the design — pass layer={design.layer("name")}, not ${typeof e == "string" ? `the bare string "${e}"` : "a plain value"}. Tokens validate the name against the design's layers at mint time.`,
@@ -536,8 +544,8 @@ function He(t) {
536
544
  );
537
545
  d.current = e.name;
538
546
  }
539
- re(() => l.registry.registerTextField(m, { name: e.name, optional: n }), [l.registry, m, e.name, n]);
540
- const c = A(
547
+ ne(() => l.registry.registerTextField(c, { name: e.name, optional: r }), [l.registry, c, e.name, r]);
548
+ const m = L(
541
549
  u.subscribe,
542
550
  () => u.textOf(e.name) ?? "",
543
551
  () => u.textOf(e.name) ?? ""
@@ -564,16 +572,16 @@ function He(t) {
564
572
  "data-sc-part": "textfield",
565
573
  "data-sc-layer": e.name,
566
574
  type: "text",
567
- value: c,
575
+ value: m,
568
576
  onChange: y,
569
- placeholder: r,
577
+ placeholder: n,
570
578
  "aria-label": t["aria-label"] ?? e.name,
571
579
  className: s,
572
580
  style: a
573
581
  }
574
582
  );
575
583
  }
576
- function We(t) {
584
+ function Je(t) {
577
585
  const e = [];
578
586
  if (t.product.options)
579
587
  try {
@@ -581,22 +589,22 @@ function We(t) {
581
589
  } catch {
582
590
  e.push("variant");
583
591
  }
584
- for (const n of t.textFields) {
585
- if (n.optional) continue;
586
- const r = (t.textOf(n.name) ?? "").trim();
587
- if (r.length === 0) {
588
- e.push(`layer:${n.name}`);
592
+ for (const r of t.textFields) {
593
+ if (r.optional) continue;
594
+ const n = (t.textOf(r.name) ?? "").trim();
595
+ if (n.length === 0) {
596
+ e.push(`layer:${r.name}`);
589
597
  continue;
590
598
  }
591
- const s = (t.seedTextOf(n.name) ?? "").trim();
592
- s.length > 0 && r === s && e.push(`layer-seed:${n.name}`);
599
+ const s = (t.seedTextOf(r.name) ?? "").trim();
600
+ s.length > 0 && n === s && e.push(`layer-seed:${r.name}`);
593
601
  }
594
602
  return t.hasRenderableElement || e.push("empty-design"), (!Number.isInteger(t.quantity) || t.quantity < 1) && e.push("quantity"), e;
595
603
  }
596
- function ze(t, e) {
597
- const n = t.options, r = n == null ? void 0 : n.combinations;
598
- if (!n || !(r != null && r.length)) return null;
599
- const s = r.find((i) => i.variantId && i.variantId === t.variantId) ?? r[0];
604
+ function Ye(t, e) {
605
+ const r = t.options, n = r == null ? void 0 : r.combinations;
606
+ if (!r || !(n != null && n.length)) return null;
607
+ const s = n.find((i) => i.variantId && i.variantId === t.variantId) ?? n[0];
600
608
  if (!s) return null;
601
609
  const a = {};
602
610
  for (const [i, o] of Object.entries(s))
@@ -604,108 +612,108 @@ function ze(t, e) {
604
612
  const l = Object.fromEntries(
605
613
  Object.keys(a).map((i) => [
606
614
  i,
607
- { key: i, affectsCombinations: !0, choices: [...new Set(r.map((o) => String(o[i] ?? "")))] }
615
+ { key: i, affectsCombinations: !0, choices: [...new Set(n.map((o) => String(o[i] ?? "")))] }
608
616
  ])
609
617
  );
610
618
  return Ie({
611
619
  productId: t.productId,
612
620
  quantity: e,
613
621
  selection: a,
614
- combinations: r,
622
+ combinations: n,
615
623
  attributes: l
616
624
  });
617
625
  }
618
- function Je(t) {
619
- const { onAddToCart: e, quantity: n = 1, children: r, className: s, style: a } = t, l = G("Editor.Buy"), { product: i, stateStore: o } = L();
626
+ function Qe(t) {
627
+ const { onAddToCart: e, quantity: r = 1, children: n, className: s, style: a } = t, l = K("Editor.Buy"), { product: i, stateStore: o } = A();
620
628
  if (!(i != null && i.productId))
621
629
  throw new R(
622
630
  "E_BUY_NO_PRODUCT",
623
631
  "<Editor.Buy> has no product context — pass `product` (with `productId`) on <Editor.Root product={…}>. Buy assembles its cart payload from the Root product and the live design state.",
624
632
  { docSlug: "embed-mode" }
625
633
  );
626
- const u = A(o.subscribe, o.getState, o.getState), m = A(
634
+ const u = L(o.subscribe, o.getState, o.getState), c = L(
627
635
  l.registry.subscribe,
628
636
  l.registry.getVersion,
629
637
  l.registry.getVersion
630
638
  ), d = I(
631
- () => We({
639
+ () => Je({
632
640
  product: i,
633
- quantity: n,
641
+ quantity: r,
634
642
  textFields: l.registry.getTextFields(),
635
643
  textOf: (S) => o.textOf(S),
636
644
  seedTextOf: (S) => o.seedTextOf(S),
637
645
  hasRenderableElement: o.hasRenderableElement()
638
646
  }),
639
647
  // eslint-disable-next-line react-hooks/exhaustive-deps
640
- [i, n, u, m]
641
- ), c = d.length === 0, [y, g] = O(!1), b = T(!1), p = se(() => {
642
- if (b.current || !c) return;
648
+ [i, r, u, c]
649
+ ), m = d.length === 0, [y, g] = O(!1), b = N(!1), p = se(() => {
650
+ if (b.current || !m) return;
643
651
  b.current = !0, g(!0);
644
652
  const S = o.getState(), q = {
645
653
  productId: i.productId,
646
654
  ...i.variantId ? { variantId: i.variantId } : {},
647
- quantity: n,
648
- cartDetail: ze(i, n),
655
+ quantity: r,
656
+ cartDetail: Ye(i, r),
649
657
  designState: S,
650
658
  serverRequest: le(S)
651
659
  };
652
660
  let C;
653
661
  try {
654
662
  C = e(q);
655
- } catch (N) {
656
- throw b.current = !1, g(!1), N;
663
+ } catch (T) {
664
+ throw b.current = !1, g(!1), T;
657
665
  }
658
666
  Promise.resolve(C).finally(() => {
659
667
  b.current = !1, g(!1);
660
668
  });
661
- }, [c, i, n, o, e]);
669
+ }, [m, i, r, o, e]);
662
670
  return /* @__PURE__ */ f(
663
671
  "button",
664
672
  {
665
673
  type: "button",
666
674
  "data-sc-part": "buy",
667
- "data-sc-buy-state": y ? "busy" : c ? "ready" : "incomplete",
675
+ "data-sc-buy-state": y ? "busy" : m ? "ready" : "incomplete",
668
676
  "data-sc-buy-missing": d.join(",") || void 0,
669
- disabled: !c || y,
677
+ disabled: !m || y,
670
678
  "aria-busy": y || void 0,
671
679
  onClick: p,
672
680
  className: s,
673
681
  style: a,
674
- children: r ?? "Add to cart"
682
+ children: n ?? "Add to cart"
675
683
  }
676
684
  );
677
685
  }
678
- const ot = {
686
+ const lt = {
679
687
  /** The one provider boundary — session, design, live state, error boundary. */
680
688
  Root: he,
681
689
  /** The editable artboard (the ONE lazy renderer boundary — D9). */
682
- Canvas: Pe,
690
+ Canvas: Ge,
683
691
  /** Live product mockup. ×N under one Root is valid. */
684
692
  Preview: pe,
685
693
  /** Form input bound to a design text layer by typed token (T1). */
686
- TextField: He,
694
+ TextField: ze,
687
695
  /** Smart commerce part: completeness + payload assembly; submit = host callback. */
688
- Buy: Je
696
+ Buy: Qe
689
697
  };
690
- function lt(t) {
698
+ function dt(t) {
691
699
  return /* @__PURE__ */ f(he, { ...t, __validation: "warn" });
692
700
  }
693
- const dt = te(
694
- function(e, n) {
695
- const { children: r, className: s, style: a, maxHeight: l, ...i } = e, [o, u] = O(null);
701
+ const ut = te(
702
+ function(e, r) {
703
+ const { children: n, className: s, style: a, maxHeight: l, ...i } = e, [o, u] = O(null);
696
704
  return $(() => {
697
- let m = !1;
705
+ let c = !1;
698
706
  return ge().then(
699
707
  (d) => {
700
- m || u(() => d);
708
+ c || u(() => d);
701
709
  },
702
710
  (d) => {
703
711
  console.error("[RealtimeCanvas] failed to load the rendering chunk:", d);
704
712
  }
705
713
  ), () => {
706
- m = !0;
714
+ c = !0;
707
715
  };
708
- }, []), o ? /* @__PURE__ */ f(o, { ref: n, selfScope: !0, maxHeight: l, className: s, style: a, ...i, children: r }) : /* @__PURE__ */ f(
716
+ }, []), o ? /* @__PURE__ */ f(o, { ref: r, selfScope: !0, maxHeight: l, className: s, style: a, ...i, children: n }) : /* @__PURE__ */ f(
709
717
  "div",
710
718
  {
711
719
  className: `sc-root${s ? ` ${s}` : ""}`,
@@ -715,24 +723,24 @@ const dt = te(
715
723
  );
716
724
  }
717
725
  );
718
- function ut(t) {
726
+ function ct(t) {
719
727
  return /* @__PURE__ */ f(pe, { ...t });
720
728
  }
721
- function ct() {
722
- const { mockups: t, isRendering: e, error: n } = L();
723
- return { mockups: t, isRendering: e, error: n };
729
+ function mt() {
730
+ const { mockups: t, isRendering: e, error: r } = A();
731
+ return { mockups: t, isRendering: e, error: r };
724
732
  }
725
733
  Re();
726
734
  export {
727
- Be as D,
735
+ De as D,
728
736
  ce as E,
729
- dt as R,
730
- ot as a,
731
- lt as b,
732
- ut as c,
737
+ ut as R,
738
+ lt as a,
739
+ dt as b,
740
+ ct as c,
733
741
  ue as d,
734
- ct as e,
735
- L as u,
736
- $e as v
742
+ mt as e,
743
+ A as u,
744
+ Fe as v
737
745
  };
738
- //# sourceMappingURL=embed-B5kewSQY.js.map
746
+ //# sourceMappingURL=embed--B8ot6Lj.js.map