@base44-preview/vite-plugin 1.0.20-pr.82.48b1960 → 1.0.20-pr.83.ee1eb29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@base44-preview/vite-plugin",
3
- "version": "1.0.20-pr.82.48b1960",
3
+ "version": "1.0.20-pr.83.ee1eb29",
4
4
  "description": "The Vite plugin for base44 based applications",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -2,28 +2,21 @@
2
2
  // Inert until the parent posts a message; no observers, rewrites, or timers
3
3
  // fire on their own.
4
4
  //
5
- // parent → child { type: "freeze-vh-units", referenceVhBase?: number, reqId?: string }
5
+ // parent → child { type: "freeze-vh-units", referenceVhBase?: number }
6
6
  // Rewrites every viewport-height unit (`vh`/`dvh`/`svh`/`lvh`) in
7
7
  // <style> + CSSOM to a CSS variable-backed expression (kills the
8
8
  // vh ↔ auto-resize feedback loop). Repeated calls update the variable,
9
9
  // so callers can rebase without recovering raw CSS. Idempotent; covers
10
- // HMR-added styles too. When `reqId` is provided, replies with
11
- // `{ type: "freeze-vh-units:ack", reqId }` immediately after accepting
12
- // the request (semantics: "received", not "fully applied" — the rewrite
13
- // is debounced and idempotent, so receipt is sufficient).
10
+ // HMR-added styles too. Fire-and-forget.
14
11
  //
15
- // parent → child { type: "measure-page-height", settleMs?: number, reqId?: string }
12
+ // parent → child { type: "measure-page-height", settleMs?: number }
16
13
  // After `settleMs` (default 2000) posts the page's measured content height
17
- // as `{ type: "page-height-measured", height }` to the requester. When
18
- // `reqId` is provided, also sends `{ type: "measure-page-height:ack", reqId }`
19
- // immediately on receipt so the requester can distinguish "request lost"
20
- // from "still waiting for measurement to settle".
14
+ // as `{ type: "page-height-measured", height }` to the requester.
21
15
 
22
16
  type IncomingMessage = {
23
17
  type?: string;
24
18
  settleMs?: number;
25
19
  referenceVhBase?: number;
26
- reqId?: string;
27
20
  };
28
21
 
29
22
  type IndexableCssRule = CSSRule & {
@@ -79,31 +72,19 @@ export function setupPageHeightBridge(): () => void {
79
72
  const onMessage = (event: MessageEvent): void => {
80
73
  const data: IncomingMessage | null = (event.data ?? null) as IncomingMessage | null;
81
74
  if (!data || typeof data !== "object") return;
82
- const ackOrigin: string =
83
- event.origin && event.origin !== "null" ? event.origin : "*";
84
75
  switch (data.type) {
85
76
  case "freeze-vh-units": {
86
77
  const override: number | undefined =
87
78
  typeof data.referenceVhBase === "number" ? data.referenceVhBase : undefined;
88
79
  controller.freezeVhUnits(override);
89
- if (typeof data.reqId === "string") {
90
- window.parent.postMessage(
91
- { type: "freeze-vh-units:ack", reqId: data.reqId },
92
- ackOrigin,
93
- );
94
- }
95
80
  return;
96
81
  }
97
82
  case "measure-page-height": {
98
83
  const settleMs: number =
99
84
  typeof data.settleMs === "number" ? data.settleMs : DEFAULT_SETTLE_MS;
100
- controller.measurePageHeight(ackOrigin, settleMs);
101
- if (typeof data.reqId === "string") {
102
- window.parent.postMessage(
103
- { type: "measure-page-height:ack", reqId: data.reqId },
104
- ackOrigin,
105
- );
106
- }
85
+ const origin: string =
86
+ event.origin && event.origin !== "null" ? event.origin : "*";
87
+ controller.measurePageHeight(origin, settleMs);
107
88
  return;
108
89
  }
109
90
  }
@@ -82,12 +82,21 @@ export function updateElementClasses(elements: Element[], classes: string): void
82
82
  }
83
83
 
84
84
  /** Set a single attribute on all provided elements. */
85
- export function updateElementAttribute(elements: Element[], attribute: string, value: string): void {
85
+ export function updateElementAttribute(
86
+ elements: Element[],
87
+ attribute: string,
88
+ value: string,
89
+ arrIndex?: number | string
90
+ ): void {
86
91
  if (!ALLOWED_ATTRIBUTES.includes(attribute)) {
87
92
  return;
88
93
  }
89
94
 
90
- elements.forEach((element) => {
95
+ const targetElements = arrIndex != null
96
+ ? elements.filter((element) => (element as HTMLElement).dataset.arrIndex === String(arrIndex))
97
+ : elements;
98
+
99
+ targetElements.forEach((element) => {
91
100
  element.setAttribute(attribute, value);
92
101
  });
93
102
  }
@@ -368,12 +368,13 @@ export function setupVisualEditAgent() {
368
368
  const updateElementAttributeAndReposition = (
369
369
  visualSelectorId: string,
370
370
  attribute: string,
371
- value: string
371
+ value: string,
372
+ arrIndex?: number | string
372
373
  ) => {
373
374
  const elements = findElementsById(visualSelectorId);
374
375
  if (elements.length === 0) return;
375
376
 
376
- updateElementAttribute(elements, attribute, value);
377
+ updateElementAttribute(elements, attribute, value, arrIndex);
377
378
 
378
379
  // Reposition overlays after attribute change (e.g. image src swap can affect layout)
379
380
  setTimeout(() => {
@@ -529,7 +530,8 @@ export function setupVisualEditAgent() {
529
530
  updateElementAttributeAndReposition(
530
531
  message.data.visualSelectorId,
531
532
  message.data.attribute,
532
- message.data.value
533
+ message.data.value,
534
+ message.data.arrIndex
533
535
  );
534
536
  } else {
535
537
  console.warn(
@@ -652,7 +654,6 @@ export function setupVisualEditAgent() {
652
654
  ? message.referenceVhBase
653
655
  : undefined
654
656
  );
655
- postAckIfRequested(event, message, "freeze-vh-units:ack");
656
657
  break;
657
658
 
658
659
  case "measure-page-height":
@@ -660,12 +661,10 @@ export function setupVisualEditAgent() {
660
661
  event.origin && event.origin !== "null" ? event.origin : "*",
661
662
  typeof message.settleMs === "number" ? message.settleMs : undefined
662
663
  );
663
- postAckIfRequested(event, message, "measure-page-height:ack");
664
664
  break;
665
665
 
666
666
  case "suppress-auto-popups":
667
667
  autoPopupSuppressor.suppress();
668
- postAckIfRequested(event, message, "suppress-auto-popups:ack");
669
668
  break;
670
669
 
671
670
  case "toggle-canvas-wheel-zoom-bridge":
@@ -758,18 +757,3 @@ export function setupVisualEditAgent() {
758
757
  // Send ready message to parent
759
758
  window.parent.postMessage({ type: "visual-edit-agent-ready" }, "*");
760
759
  }
761
-
762
- // Post `{type: ackType, reqId}` back to the parent whenever the incoming
763
- // message included a `reqId`. Lets the canvas (parent) detect dropped or
764
- // late-arriving messages and retry — see postMessageWithAck.ts on the
765
- // apper side. No-op when `reqId` is missing (backward-compatible).
766
- export function postAckIfRequested(
767
- event: MessageEvent,
768
- message: { reqId?: unknown },
769
- ackType: string,
770
- ): void {
771
- if (typeof message.reqId !== "string") return;
772
- const ackOrigin =
773
- event.origin && event.origin !== "null" ? event.origin : "*";
774
- window.parent.postMessage({ type: ackType, reqId: message.reqId }, ackOrigin);
775
- }
@@ -69,6 +69,9 @@ export class StaticArrayProcessor {
69
69
  path: NodePath<t.JSXOpeningElement>,
70
70
  callbackParam: string
71
71
  ): string | null {
72
+ const imageSrcFieldPath = this.findImageSrcFieldPath(path, callbackParam);
73
+ if (imageSrcFieldPath) return imageSrcFieldPath;
74
+
72
75
  const parentElement = path.parentPath;
73
76
  if (!parentElement?.isJSXElement()) return null;
74
77
 
@@ -80,6 +83,36 @@ export class StaticArrayProcessor {
80
83
  return null;
81
84
  }
82
85
 
86
+ private findImageSrcFieldPath(
87
+ path: NodePath<t.JSXOpeningElement>,
88
+ callbackParam: string
89
+ ): string | null {
90
+ const elementName = this.getElementName(path);
91
+ if (elementName !== "img" && elementName !== "Image") return null;
92
+
93
+ for (const attr of path.node.attributes) {
94
+ if (
95
+ !this.types.isJSXAttribute(attr) ||
96
+ !this.types.isJSXIdentifier(attr.name) ||
97
+ attr.name.name !== "src" ||
98
+ !attr.value ||
99
+ !this.types.isJSXExpressionContainer(attr.value)
100
+ ) {
101
+ continue;
102
+ }
103
+
104
+ const expression = attr.value.expression;
105
+ if (
106
+ this.types.isMemberExpression(expression) ||
107
+ this.types.isOptionalMemberExpression(expression)
108
+ ) {
109
+ return this.extractFieldPathFromExpression(expression, callbackParam);
110
+ }
111
+ }
112
+
113
+ return null;
114
+ }
115
+
83
116
  private extractFieldPathFromChild(
84
117
  child: NodePath<t.JSXElement["children"][number]>,
85
118
  callbackParam: string
@@ -92,6 +125,17 @@ export class StaticArrayProcessor {
92
125
  return this.extractFieldPath(expression, callbackParam);
93
126
  }
94
127
 
128
+ private extractFieldPathFromExpression(
129
+ expr: t.MemberExpression | t.OptionalMemberExpression,
130
+ callbackParam: string
131
+ ): string | null {
132
+ const parts = this.collectMemberExpressionPartsFromNode(expr);
133
+ if (!parts) return null;
134
+
135
+ const { rootName, propertyNames } = parts;
136
+ return rootName === callbackParam ? propertyNames.join(".") : null;
137
+ }
138
+
95
139
  private extractFieldPath(
96
140
  expr: NodePath<t.MemberExpression>,
97
141
  callbackParam: string
@@ -122,6 +166,35 @@ export class StaticArrayProcessor {
122
166
  return { rootName: current.node.name, propertyNames };
123
167
  }
124
168
 
169
+ private collectMemberExpressionPartsFromNode(
170
+ expr: t.MemberExpression | t.OptionalMemberExpression
171
+ ): { rootName: string; propertyNames: string[] } | null {
172
+ const propertyNames: string[] = [];
173
+ let current: t.Expression = expr;
174
+
175
+ while (
176
+ this.types.isMemberExpression(current) ||
177
+ this.types.isOptionalMemberExpression(current)
178
+ ) {
179
+ const property = current.property;
180
+ if (!this.types.isIdentifier(property)) return null;
181
+
182
+ propertyNames.unshift(property.name);
183
+ current = current.object as t.Expression;
184
+ }
185
+
186
+ if (!this.types.isIdentifier(current)) return null;
187
+
188
+ return { rootName: current.name, propertyNames };
189
+ }
190
+
191
+ private getElementName(path: NodePath<t.JSXOpeningElement>): string | null {
192
+ const name = path.node.name;
193
+ if (this.types.isJSXIdentifier(name)) return name.name;
194
+ if (this.types.isJSXMemberExpression(name)) return name.property.name;
195
+ return null;
196
+ }
197
+
125
198
  private ensureIndexParam(arrayInfo: ArrayMapInfo): string {
126
199
  if (arrayInfo.indexParam) {
127
200
  return arrayInfo.indexParam;