@base44-preview/vite-plugin 1.0.40-pr.124.62cc52a → 1.0.41-pr.125.31ff72d
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/README.md +23 -0
- package/dist/html-injections-plugin.d.ts +15 -0
- package/dist/html-injections-plugin.d.ts.map +1 -1
- package/dist/html-injections-plugin.js +63 -1
- package/dist/html-injections-plugin.js.map +1 -1
- package/dist/injections/ssr-mount-signal.d.ts +2 -0
- package/dist/injections/ssr-mount-signal.d.ts.map +1 -0
- package/dist/injections/ssr-mount-signal.js +18 -0
- package/dist/injections/ssr-mount-signal.js.map +1 -0
- package/package.json +1 -1
- package/src/html-injections-plugin.ts +70 -1
- package/src/injections/ssr-mount-signal.ts +15 -0
package/README.md
CHANGED
|
@@ -140,6 +140,29 @@ The **visual edit agent** is the exception. It's a larger module (~560 lines) th
|
|
|
140
140
|
|
|
141
141
|
In **production**, an inline analytics tracker script is injected instead.
|
|
142
142
|
|
|
143
|
+
### Server-rendered documents (`base44:document`)
|
|
144
|
+
|
|
145
|
+
`transformIndexHtml` never runs for an app whose HTML document is rendered by the framework (TanStack Start and other SSR setups have no `index.html`). Those apps import the same scripts as a module and render them at the end of `<body>`:
|
|
146
|
+
|
|
147
|
+
```jsx
|
|
148
|
+
import { Base44Scripts } from "base44:document";
|
|
149
|
+
|
|
150
|
+
function RootDocument({ children }) {
|
|
151
|
+
return (
|
|
152
|
+
<html>
|
|
153
|
+
<head><HeadContent /></head>
|
|
154
|
+
<body data-react-root="true">
|
|
155
|
+
{children}
|
|
156
|
+
<Scripts />
|
|
157
|
+
<Base44Scripts />
|
|
158
|
+
</body>
|
|
159
|
+
</html>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
The module is virtual: the plugin decides its contents from the same options, command and env as the `index.html` injections, so dev gets the sandbox scripts (plus `ssr-mount-signal.js`, which reports the mount on `DOMContentLoaded` because a hydrated page never triggers the mutation observer) and production gets the analytics tracker. `base44DocumentScripts()` returns the raw `{ src }` / `{ children }` list for a non-React document. Keep the tags at the end of `<body>`, not in `<head>`: the preview proxy prepends its own scripts there, and React 19 fails hydration of a head it did not render.
|
|
165
|
+
|
|
143
166
|
### Local Development (Visual Edit Agent)
|
|
144
167
|
|
|
145
168
|
To iterate on the visual edit agent locally without publishing:
|
|
@@ -8,6 +8,20 @@ import type { Connect, Plugin } from "vite";
|
|
|
8
8
|
export declare const BUNDLED_INJECTION_PREFIX = "virtual:base44-vite-plugin/";
|
|
9
9
|
/** This file lives in dist/ once built, so its directory is the served root. */
|
|
10
10
|
export declare const PLUGIN_DIST_DIR: string;
|
|
11
|
+
/**
|
|
12
|
+
* `base44:document` — the same scripts `transformIndexHtml` injects, for apps
|
|
13
|
+
* whose HTML document is rendered by a framework (TanStack Start, and any other
|
|
14
|
+
* SSR setup) and never passes through `index.html`. The root document renders
|
|
15
|
+
* `<Base44Scripts />` at the end of `<body>`; the plugin decides what that is
|
|
16
|
+
* from its own options, the command and the env, exactly as for `index.html`.
|
|
17
|
+
*/
|
|
18
|
+
export declare const DOCUMENT_SPECIFIER = "base44:document";
|
|
19
|
+
type DocumentScript = {
|
|
20
|
+
src: string;
|
|
21
|
+
} | {
|
|
22
|
+
children: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function documentModule(scripts: DocumentScript[]): string;
|
|
11
25
|
export declare function resolveBundledInjection(id: string, distDir?: string): string | undefined;
|
|
12
26
|
/**
|
|
13
27
|
* Bundled dev mounts no static/transform middleware, so the visual-edit agent's
|
|
@@ -21,4 +35,5 @@ export declare function htmlInjectionsPlugin({ hmrNotifier, navigationNotifier,
|
|
|
21
35
|
visualEditAgent: boolean;
|
|
22
36
|
analyticsTracker: boolean;
|
|
23
37
|
}): Plugin[];
|
|
38
|
+
export {};
|
|
24
39
|
//# sourceMappingURL=html-injections-plugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html-injections-plugin.d.ts","sourceRoot":"","sources":["../src/html-injections-plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAoC,MAAM,MAAM,CAAC;AAiD9E;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,gCAAgC,CAAC;AAgDtE,gFAAgF;AAChF,eAAO,MAAM,eAAe,QAA+C,CAAC;
|
|
1
|
+
{"version":3,"file":"html-injections-plugin.d.ts","sourceRoot":"","sources":["../src/html-injections-plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAoC,MAAM,MAAM,CAAC;AAiD9E;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,gCAAgC,CAAC;AAgDtE,gFAAgF;AAChF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAI5E;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,oBAAoB,CAAC;AAGpD,KAAK,cAAc,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,MAAM,CA2BhE;AAED,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,SAAkB,GAAG,MAAM,GAAG,SAAS,CAGjG;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,IACzC,KAAK,OAAO,CAAC,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC,YAAY,UA0BtF;AAED,wBAAgB,oBAAoB,CAAC,EACnC,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,gBAAgB,GACjB,EAAE;IACD,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;CAC3B,GAAG,MAAM,EAAE,CA6JX"}
|
|
@@ -89,6 +89,44 @@ const CONTENT_TYPES = {
|
|
|
89
89
|
/** This file lives in dist/ once built, so its directory is the served root. */
|
|
90
90
|
export const PLUGIN_DIST_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
91
91
|
const VISUAL_EDIT_AGENT_FILE = "statics/index.mjs";
|
|
92
|
+
const SSR_MOUNT_SIGNAL_FILE = "injections/ssr-mount-signal.js";
|
|
93
|
+
/**
|
|
94
|
+
* `base44:document` — the same scripts `transformIndexHtml` injects, for apps
|
|
95
|
+
* whose HTML document is rendered by a framework (TanStack Start, and any other
|
|
96
|
+
* SSR setup) and never passes through `index.html`. The root document renders
|
|
97
|
+
* `<Base44Scripts />` at the end of `<body>`; the plugin decides what that is
|
|
98
|
+
* from its own options, the command and the env, exactly as for `index.html`.
|
|
99
|
+
*/
|
|
100
|
+
export const DOCUMENT_SPECIFIER = "base44:document";
|
|
101
|
+
const DOCUMENT_RESOLVED = "\0base44:document";
|
|
102
|
+
export function documentModule(scripts) {
|
|
103
|
+
return `
|
|
104
|
+
import { createElement, Fragment } from "react";
|
|
105
|
+
|
|
106
|
+
const SCRIPTS = ${JSON.stringify(scripts)};
|
|
107
|
+
|
|
108
|
+
export function base44DocumentScripts() {
|
|
109
|
+
return SCRIPTS;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function Base44Scripts() {
|
|
113
|
+
return createElement(
|
|
114
|
+
Fragment,
|
|
115
|
+
null,
|
|
116
|
+
...SCRIPTS.map((script, index) =>
|
|
117
|
+
"src" in script
|
|
118
|
+
? createElement("script", { key: index, type: "module", src: script.src })
|
|
119
|
+
: createElement("script", {
|
|
120
|
+
key: index,
|
|
121
|
+
type: "module",
|
|
122
|
+
suppressHydrationWarning: true,
|
|
123
|
+
dangerouslySetInnerHTML: { __html: script.children },
|
|
124
|
+
}),
|
|
125
|
+
),
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
`;
|
|
129
|
+
}
|
|
92
130
|
export function resolveBundledInjection(id, distDir = PLUGIN_DIST_DIR) {
|
|
93
131
|
if (!id.startsWith(BUNDLED_INJECTION_PREFIX))
|
|
94
132
|
return undefined;
|
|
@@ -242,6 +280,30 @@ export function htmlInjectionsPlugin({ hmrNotifier, navigationNotifier, visualEd
|
|
|
242
280
|
},
|
|
243
281
|
},
|
|
244
282
|
};
|
|
245
|
-
|
|
283
|
+
// The framework's dev server is middleware-based, so dev scripts keep their
|
|
284
|
+
// node_modules URLs even when `bundled` is set; the SSR mount signal stands in
|
|
285
|
+
// for the mutation-driven observer, which never fires on a hydrated page.
|
|
286
|
+
const documentScripts = () => {
|
|
287
|
+
const tags = isServe ? devTags() : tagsFor("production");
|
|
288
|
+
const scripts = tags.map((tag) => typeof tag.children === "string"
|
|
289
|
+
? { children: tag.children }
|
|
290
|
+
: { src: String(tag.attrs?.src).replace(BUNDLED_INJECTION_PREFIX, `${DIST_URL_PREFIX}/`) });
|
|
291
|
+
if (isServe)
|
|
292
|
+
scripts.push({ src: `${DIST_URL_PREFIX}/${SSR_MOUNT_SIGNAL_FILE}` });
|
|
293
|
+
return scripts;
|
|
294
|
+
};
|
|
295
|
+
const document = {
|
|
296
|
+
name: "base44-document",
|
|
297
|
+
// Ahead of Vite's own resolution so the bare `base44:` specifier is never
|
|
298
|
+
// mistaken for a URL protocol.
|
|
299
|
+
enforce: "pre",
|
|
300
|
+
resolveId(id) {
|
|
301
|
+
return id === DOCUMENT_SPECIFIER ? DOCUMENT_RESOLVED : null;
|
|
302
|
+
},
|
|
303
|
+
load(id) {
|
|
304
|
+
return id === DOCUMENT_RESOLVED ? documentModule(documentScripts()) : null;
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
return [dev, devBundled, production, document];
|
|
246
308
|
}
|
|
247
309
|
//# sourceMappingURL=html-injections-plugin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html-injections-plugin.js","sourceRoot":"","sources":["../src/html-injections-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAahD,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BhC,CAAC;AAEF,MAAM,eAAe,GAAG,wCAAwC,CAAC;AACjE;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,6BAA6B,CAAC;AAEtE,MAAM,UAAU,GAA8B;IAC5C,eAAe,EAAE;QACf,IAAI,EAAE,yCAAyC;QAC/C,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;KACZ;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,sCAAsC;QAC5C,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;KACZ;IACD,WAAW,EAAE;QACX,IAAI,EAAE,oCAAoC;QAC1C,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;KACZ;IACD,kBAAkB,EAAE;QAClB,IAAI,EAAE,mCAAmC;QACzC,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;KACZ;IACD,kBAAkB,EAAE;QAClB,IAAI,EAAE,4CAA4C;QAClD,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,IAAI;KAClB;IACD,cAAc,EAAE;QACd,IAAI,EAAE,wCAAwC;QAC9C,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,IAAI;KAClB;IACD,gBAAgB,EAAE;QAChB,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,YAAY;QAClB,aAAa,EAAE,wBAAwB;KACxC;CACF,CAAC;AAEF,MAAM,aAAa,GAA2B;IAC5C,KAAK,EAAE,iBAAiB;IACxB,MAAM,EAAE,iBAAiB;IACzB,MAAM,EAAE,kBAAkB;CAC3B,CAAC;AAEF,gFAAgF;AAChF,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5E,MAAM,sBAAsB,GAAG,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"html-injections-plugin.js","sourceRoot":"","sources":["../src/html-injections-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAahD,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BhC,CAAC;AAEF,MAAM,eAAe,GAAG,wCAAwC,CAAC;AACjE;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,6BAA6B,CAAC;AAEtE,MAAM,UAAU,GAA8B;IAC5C,eAAe,EAAE;QACf,IAAI,EAAE,yCAAyC;QAC/C,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;KACZ;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,sCAAsC;QAC5C,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;KACZ;IACD,WAAW,EAAE;QACX,IAAI,EAAE,oCAAoC;QAC1C,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;KACZ;IACD,kBAAkB,EAAE;QAClB,IAAI,EAAE,mCAAmC;QACzC,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;KACZ;IACD,kBAAkB,EAAE;QAClB,IAAI,EAAE,4CAA4C;QAClD,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,IAAI;KAClB;IACD,cAAc,EAAE;QACd,IAAI,EAAE,wCAAwC;QAC9C,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,IAAI;KAClB;IACD,gBAAgB,EAAE;QAChB,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,YAAY;QAClB,aAAa,EAAE,wBAAwB;KACxC;CACF,CAAC;AAEF,MAAM,aAAa,GAA2B;IAC5C,KAAK,EAAE,iBAAiB;IACxB,MAAM,EAAE,iBAAiB;IACzB,MAAM,EAAE,kBAAkB;CAC3B,CAAC;AAEF,gFAAgF;AAChF,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5E,MAAM,sBAAsB,GAAG,mBAAmB,CAAC;AACnD,MAAM,qBAAqB,GAAG,gCAAgC,CAAC;AAE/D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AACpD,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AAI9C,MAAM,UAAU,cAAc,CAAC,OAAyB;IACtD,OAAO;;;kBAGS,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;CAsBxC,CAAC;AACF,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,EAAU,EAAE,OAAO,GAAG,eAAe;IAC3E,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,wBAAwB,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/D,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC,CAAC;AACvE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,OAAO,CAAC,GAA4B,EAAE,GAAmB,EAAE,IAA0B,EAAE,EAAE;QACvF,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,eAAe,GAAG,CAAC;YAAE,OAAO,IAAI,EAAE,CAAC;QAC1D,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM;YAAE,OAAO,IAAI,EAAE,CAAC;QACjE,IAAI,QAAgB,CAAC;QACrB,IAAI,CAAC;YACH,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QACnD,IACE,CAAC,IAAI;YACL,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC;YACxC,CAAC,UAAU,CAAC,QAAQ,CAAC;YACrB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,EAC5B,CAAC;YACD,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QACD,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;QACrB,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QACpC,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;QAC3C,wEAAwE;QACxE,gBAAgB,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpE,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,EACnC,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,gBAAgB,GAMjB;IACC,6EAA6E;IAC7E,yEAAyE;IACzE,qEAAqE;IACrE,MAAM,iBAAiB,GAA4B;QACjD,eAAe,EAAE,IAAI;QACrB,YAAY,EAAE,IAAI;QAClB,WAAW;QACX,kBAAkB;QAClB,kBAAkB,EAAE,IAAI;QACxB,cAAc,EAAE,IAAI;QACpB,gBAAgB;KACjB,CAAC;IAEF,sEAAsE;IACtE,kDAAkD;IAClD,IAAI,WAAW,GAA2B,EAAE,CAAC;IAC7C,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,MAAM,OAAO,GAAG,CAAC,IAA0B,EAAuB,EAAE,CAClE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;SACvB,MAAM,CACL,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,EAAE,CACnB,iBAAiB,CAAC,GAAG,CAAC;QACtB,SAAS,CAAC,IAAI,KAAK,IAAI;QACvB,CAAC,CAAC,SAAS,CAAC,WAAW,IAAI,OAAO,CAAC,CACtC;SACA,GAAG,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAqB,EAAE;QACxC,IAAI,SAAS,CAAC,aAAa,EAAE,CAAC;YAC5B,uEAAuE;YACvE,MAAM,OAAO,GAAG,SAAS,CAAC,aAAa,CAAC,OAAO,CAC7C,2BAA2B,EAC3B,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CACzD,CAAC;YACF,OAAO;gBACL,GAAG,EAAE,QAAQ;gBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACzB,QAAQ,EAAE,OAAO;gBACjB,QAAQ,EAAE,SAAS,CAAC,QAAQ;aAC7B,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,GAAG,OAAO;YACjB,CAAC,CAAC,GAAG,wBAAwB,GAAG,SAAS,CAAC,IAAI,EAAE;YAChD,CAAC,CAAC,GAAG,eAAe,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC;QAC3C,OAAO;YACL,GAAG,EAAE,QAAQ;YACb,KAAK,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC9B,QAAQ,EAAE,SAAS,CAAC,QAAQ;SAC7B,CAAC;IACJ,CAAC,CAAC,CAAC;IAEP,MAAM,kBAAkB,GAAG,GAAsB,EAAE,CAAC,CAAC;QACnD,GAAG,EAAE,QAAQ;QACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACzB,QAAQ,EAAE;YACR,mCAAmC;YACnC,4EAA4E;YAC5E,gCAAgC;YAChC,0CAA0C;YAC1C,UAAU,eAAe,sBAAsB;YAC/C,eAAe;YACf,oBAAoB;YACpB,uFAAuF;YACvF,QAAQ;YACR,2EAA2E;YAC3E,GAAG;SACJ,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,QAAQ,EAAE,MAAM;KACjB,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,eAAe;YAAE,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,MAAM,GAAG,GAAW;QAClB,IAAI,EAAE,iBAAiB;QACvB,cAAc,CAAC,MAAM;YACnB,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACpD,yEAAyE;YACzE,uEAAuE;YACvE,OAAO,GAAG,MAAM,CAAC,OAAO,KAAK,OAAO,CAAC;YACrC,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;QACD,eAAe,CAAC,MAAqB;YACnC,IAAI,CAAC,OAAO;gBAAE,OAAO;YACrB,IAAI,eAAe,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,sBAAsB,CAAC,CAAC,EAAE,CAAC;gBACvF,OAAO,CAAC,IAAI,CACV,qBAAqB,sBAAsB,oBAAoB,eAAe,IAAI;oBAChF,0DAA0D,CAC7D,CAAC;YACJ,CAAC;YACD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,mBAAmB,CAAC,eAAe,CAAC,CAAC,CAAC;QAC/D,CAAC;QACD,kBAAkB,EAAE;YAClB,OAAO;gBACL,OAAO,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9C,CAAC;SACF;KACF,CAAC;IAEF,4EAA4E;IAC5E,+EAA+E;IAC/E,8EAA8E;IAC9E,8DAA8D;IAC9D,MAAM,UAAU,GAAW;QACzB,IAAI,EAAE,yBAAyB;QAC/B,SAAS,CAAC,EAAE;YACV,OAAO,uBAAuB,CAAC,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,kBAAkB,EAAE;YAClB,KAAK,EAAE,KAAK;YACZ,OAAO;gBACL,OAAO,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,CAAC;SACF;KACF,CAAC;IAEF,MAAM,UAAU,GAAW;QACzB,IAAI,EAAE,4BAA4B;QAClC,kBAAkB,EAAE;YAClB,OAAO;gBACL,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YAC9C,CAAC;SACF;KACF,CAAC;IAEF,4EAA4E;IAC5E,+EAA+E;IAC/E,0EAA0E;IAC1E,MAAM,eAAe,GAAG,GAAqB,EAAE;QAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACzD,MAAM,OAAO,GAAqB,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACjD,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ;YAC9B,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE;YAC5B,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,wBAAwB,EAAE,GAAG,eAAe,GAAG,CAAC,EAAE,CAC7F,CAAC;QACF,IAAI,OAAO;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,eAAe,IAAI,qBAAqB,EAAE,EAAE,CAAC,CAAC;QAClF,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAW;QACvB,IAAI,EAAE,iBAAiB;QACvB,0EAA0E;QAC1E,+BAA+B;QAC/B,OAAO,EAAE,KAAK;QACd,SAAS,CAAC,EAAE;YACV,OAAO,EAAE,KAAK,kBAAkB,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,EAAE;YACL,OAAO,EAAE,KAAK,iBAAiB,CAAC,CAAC,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7E,CAAC;KACF,CAAC;IAEF,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssr-mount-signal.d.ts","sourceRoot":"","sources":["../../src/injections/ssr-mount-signal.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// A server-rendered page hydrates in place and never mutates the DOM, so the
|
|
2
|
+
// mount observer's MutationObserver never fires. Report the mount once the
|
|
3
|
+
// document is parsed instead.
|
|
4
|
+
if (window.self !== window.top) {
|
|
5
|
+
const report = () => {
|
|
6
|
+
const mounted = document.body.querySelectorAll("[data-source-location], [data-dynamic-content]").length > 0;
|
|
7
|
+
if (mounted)
|
|
8
|
+
window.parent?.postMessage({ type: "sandbox:onMounted" }, "*");
|
|
9
|
+
};
|
|
10
|
+
if (document.readyState === "loading") {
|
|
11
|
+
document.addEventListener("DOMContentLoaded", report, { once: true });
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
report();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=ssr-mount-signal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssr-mount-signal.js","sourceRoot":"","sources":["../../src/injections/ssr-mount-signal.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,2EAA2E;AAC3E,8BAA8B;AAC9B,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,MAAM,OAAO,GACX,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,gDAAgD,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QAC9F,IAAI,OAAO;YAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,GAAG,CAAC,CAAC;IAC9E,CAAC,CAAC;IACF,IAAI,QAAQ,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACtC,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACxE,CAAC;SAAM,CAAC;QACN,MAAM,EAAE,CAAC;IACX,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -107,6 +107,48 @@ const CONTENT_TYPES: Record<string, string> = {
|
|
|
107
107
|
/** This file lives in dist/ once built, so its directory is the served root. */
|
|
108
108
|
export const PLUGIN_DIST_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
109
109
|
const VISUAL_EDIT_AGENT_FILE = "statics/index.mjs";
|
|
110
|
+
const SSR_MOUNT_SIGNAL_FILE = "injections/ssr-mount-signal.js";
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* `base44:document` — the same scripts `transformIndexHtml` injects, for apps
|
|
114
|
+
* whose HTML document is rendered by a framework (TanStack Start, and any other
|
|
115
|
+
* SSR setup) and never passes through `index.html`. The root document renders
|
|
116
|
+
* `<Base44Scripts />` at the end of `<body>`; the plugin decides what that is
|
|
117
|
+
* from its own options, the command and the env, exactly as for `index.html`.
|
|
118
|
+
*/
|
|
119
|
+
export const DOCUMENT_SPECIFIER = "base44:document";
|
|
120
|
+
const DOCUMENT_RESOLVED = "\0base44:document";
|
|
121
|
+
|
|
122
|
+
type DocumentScript = { src: string } | { children: string };
|
|
123
|
+
|
|
124
|
+
export function documentModule(scripts: DocumentScript[]): string {
|
|
125
|
+
return `
|
|
126
|
+
import { createElement, Fragment } from "react";
|
|
127
|
+
|
|
128
|
+
const SCRIPTS = ${JSON.stringify(scripts)};
|
|
129
|
+
|
|
130
|
+
export function base44DocumentScripts() {
|
|
131
|
+
return SCRIPTS;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function Base44Scripts() {
|
|
135
|
+
return createElement(
|
|
136
|
+
Fragment,
|
|
137
|
+
null,
|
|
138
|
+
...SCRIPTS.map((script, index) =>
|
|
139
|
+
"src" in script
|
|
140
|
+
? createElement("script", { key: index, type: "module", src: script.src })
|
|
141
|
+
: createElement("script", {
|
|
142
|
+
key: index,
|
|
143
|
+
type: "module",
|
|
144
|
+
suppressHydrationWarning: true,
|
|
145
|
+
dangerouslySetInnerHTML: { __html: script.children },
|
|
146
|
+
}),
|
|
147
|
+
),
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
`;
|
|
151
|
+
}
|
|
110
152
|
|
|
111
153
|
export function resolveBundledInjection(id: string, distDir = PLUGIN_DIST_DIR): string | undefined {
|
|
112
154
|
if (!id.startsWith(BUNDLED_INJECTION_PREFIX)) return undefined;
|
|
@@ -286,5 +328,32 @@ export function htmlInjectionsPlugin({
|
|
|
286
328
|
},
|
|
287
329
|
};
|
|
288
330
|
|
|
289
|
-
|
|
331
|
+
// The framework's dev server is middleware-based, so dev scripts keep their
|
|
332
|
+
// node_modules URLs even when `bundled` is set; the SSR mount signal stands in
|
|
333
|
+
// for the mutation-driven observer, which never fires on a hydrated page.
|
|
334
|
+
const documentScripts = (): DocumentScript[] => {
|
|
335
|
+
const tags = isServe ? devTags() : tagsFor("production");
|
|
336
|
+
const scripts: DocumentScript[] = tags.map((tag) =>
|
|
337
|
+
typeof tag.children === "string"
|
|
338
|
+
? { children: tag.children }
|
|
339
|
+
: { src: String(tag.attrs?.src).replace(BUNDLED_INJECTION_PREFIX, `${DIST_URL_PREFIX}/`) }
|
|
340
|
+
);
|
|
341
|
+
if (isServe) scripts.push({ src: `${DIST_URL_PREFIX}/${SSR_MOUNT_SIGNAL_FILE}` });
|
|
342
|
+
return scripts;
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const document: Plugin = {
|
|
346
|
+
name: "base44-document",
|
|
347
|
+
// Ahead of Vite's own resolution so the bare `base44:` specifier is never
|
|
348
|
+
// mistaken for a URL protocol.
|
|
349
|
+
enforce: "pre",
|
|
350
|
+
resolveId(id) {
|
|
351
|
+
return id === DOCUMENT_SPECIFIER ? DOCUMENT_RESOLVED : null;
|
|
352
|
+
},
|
|
353
|
+
load(id) {
|
|
354
|
+
return id === DOCUMENT_RESOLVED ? documentModule(documentScripts()) : null;
|
|
355
|
+
},
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
return [dev, devBundled, production, document];
|
|
290
359
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// A server-rendered page hydrates in place and never mutates the DOM, so the
|
|
2
|
+
// mount observer's MutationObserver never fires. Report the mount once the
|
|
3
|
+
// document is parsed instead.
|
|
4
|
+
if (window.self !== window.top) {
|
|
5
|
+
const report = () => {
|
|
6
|
+
const mounted =
|
|
7
|
+
document.body.querySelectorAll("[data-source-location], [data-dynamic-content]").length > 0;
|
|
8
|
+
if (mounted) window.parent?.postMessage({ type: "sandbox:onMounted" }, "*");
|
|
9
|
+
};
|
|
10
|
+
if (document.readyState === "loading") {
|
|
11
|
+
document.addEventListener("DOMContentLoaded", report, { once: true });
|
|
12
|
+
} else {
|
|
13
|
+
report();
|
|
14
|
+
}
|
|
15
|
+
}
|