@base44-preview/vite-plugin 1.0.20-pr.83.ee1eb29 → 1.0.20-pr.84.a80f99c

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.83.ee1eb29",
3
+ "version": "1.0.20-pr.84.a80f99c",
4
4
  "description": "The Vite plugin for base44 based applications",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -32,6 +32,26 @@ if (window.self !== window.top) {
32
32
  // Handle browser back/forward navigation
33
33
  window.addEventListener("popstate", notifyNavigation);
34
34
 
35
+ // Parent-driven CLIENT-SIDE navigation (no full reload). The canvas keeps a
36
+ // single pre-booted iframe and switches which page it shows by posting
37
+ // `navigate-to-route` instead of swapping `src`. We pushState (or replaceState)
38
+ // to the new path and dispatch a synthetic popstate so client routers
39
+ // (React Router et al.) re-render the matched route. `pushState`/`replaceState`
40
+ // are already patched above to fire `notifyNavigation`, so the parent still
41
+ // receives the resulting `app_changed_url` ack and can confirm the switch.
42
+ window.addEventListener("message", (event) => {
43
+ const data = event.data;
44
+ if (!data || data.type !== "navigate-to-route") return;
45
+ const path = data.path;
46
+ if (typeof path !== "string" || !path.startsWith("/")) return;
47
+ if (data.replace) {
48
+ history.replaceState(history.state, "", path);
49
+ } else {
50
+ history.pushState(history.state, "", path);
51
+ }
52
+ window.dispatchEvent(new PopStateEvent("popstate"));
53
+ });
54
+
35
55
  // Notify initial URL on load
36
56
  window.parent?.postMessage(
37
57
  {
@@ -82,21 +82,12 @@ 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(
86
- elements: Element[],
87
- attribute: string,
88
- value: string,
89
- arrIndex?: number | string
90
- ): void {
85
+ export function updateElementAttribute(elements: Element[], attribute: string, value: string): void {
91
86
  if (!ALLOWED_ATTRIBUTES.includes(attribute)) {
92
87
  return;
93
88
  }
94
89
 
95
- const targetElements = arrIndex != null
96
- ? elements.filter((element) => (element as HTMLElement).dataset.arrIndex === String(arrIndex))
97
- : elements;
98
-
99
- targetElements.forEach((element) => {
90
+ elements.forEach((element) => {
100
91
  element.setAttribute(attribute, value);
101
92
  });
102
93
  }
@@ -368,13 +368,12 @@ export function setupVisualEditAgent() {
368
368
  const updateElementAttributeAndReposition = (
369
369
  visualSelectorId: string,
370
370
  attribute: string,
371
- value: string,
372
- arrIndex?: number | string
371
+ value: string
373
372
  ) => {
374
373
  const elements = findElementsById(visualSelectorId);
375
374
  if (elements.length === 0) return;
376
375
 
377
- updateElementAttribute(elements, attribute, value, arrIndex);
376
+ updateElementAttribute(elements, attribute, value);
378
377
 
379
378
  // Reposition overlays after attribute change (e.g. image src swap can affect layout)
380
379
  setTimeout(() => {
@@ -530,8 +529,7 @@ export function setupVisualEditAgent() {
530
529
  updateElementAttributeAndReposition(
531
530
  message.data.visualSelectorId,
532
531
  message.data.attribute,
533
- message.data.value,
534
- message.data.arrIndex
532
+ message.data.value
535
533
  );
536
534
  } else {
537
535
  console.warn(
@@ -69,9 +69,6 @@ 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
-
75
72
  const parentElement = path.parentPath;
76
73
  if (!parentElement?.isJSXElement()) return null;
77
74
 
@@ -83,36 +80,6 @@ export class StaticArrayProcessor {
83
80
  return null;
84
81
  }
85
82
 
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
-
116
83
  private extractFieldPathFromChild(
117
84
  child: NodePath<t.JSXElement["children"][number]>,
118
85
  callbackParam: string
@@ -125,17 +92,6 @@ export class StaticArrayProcessor {
125
92
  return this.extractFieldPath(expression, callbackParam);
126
93
  }
127
94
 
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
-
139
95
  private extractFieldPath(
140
96
  expr: NodePath<t.MemberExpression>,
141
97
  callbackParam: string
@@ -166,35 +122,6 @@ export class StaticArrayProcessor {
166
122
  return { rootName: current.node.name, propertyNames };
167
123
  }
168
124
 
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
-
198
125
  private ensureIndexParam(arrayInfo: ArrayMapInfo): string {
199
126
  if (arrayInfo.indexParam) {
200
127
  return arrayInfo.indexParam;