@ecopages/react 0.2.0-alpha.9 → 0.2.1
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/CHANGELOG.md +13 -11
- package/README.md +10 -0
- package/package.json +6 -6
- package/src/react-hmr-strategy.d.ts +4 -2
- package/src/react-hmr-strategy.js +36 -3
- package/src/react-renderer.d.ts +25 -37
- package/src/react-renderer.js +190 -142
- package/src/react.plugin.d.ts +0 -12
- package/src/react.plugin.js +2 -13
- package/src/services/react-bundle.service.d.ts +3 -1
- package/src/services/react-bundle.service.js +20 -2
- package/src/services/react-hmr-page-metadata-cache.d.ts +9 -0
- package/src/services/react-hmr-page-metadata-cache.js +18 -2
- package/src/services/react-hydration-asset.service.d.ts +7 -6
- package/src/services/react-hydration-asset.service.js +26 -14
- package/src/services/react-page-module.service.js +5 -2
- package/src/services/react-runtime-bundle.service.d.ts +2 -0
- package/src/services/react-runtime-bundle.service.js +5 -0
- package/src/utils/client-graph-boundary-plugin.js +2 -2
- package/src/utils/declared-modules.js +4 -1
- package/src/utils/hydration-scripts.d.ts +1 -3
- package/src/utils/hydration-scripts.js +31 -19
- package/src/react-hmr-strategy.ts +0 -386
- package/src/react-renderer.ts +0 -803
- package/src/react.plugin.ts +0 -276
- package/src/router-adapter.ts +0 -95
- package/src/services/react-bundle.service.ts +0 -108
- package/src/services/react-hmr-page-metadata-cache.ts +0 -24
- package/src/services/react-hydration-asset.service.ts +0 -263
- package/src/services/react-page-module.service.ts +0 -224
- package/src/services/react-runtime-bundle.service.ts +0 -172
- package/src/utils/client-graph-boundary-plugin.ts +0 -831
- package/src/utils/client-only.ts +0 -27
- package/src/utils/declared-modules.ts +0 -99
- package/src/utils/dynamic.ts +0 -27
- package/src/utils/hmr-scripts.ts +0 -47
- package/src/utils/html-boundary.ts +0 -66
- package/src/utils/hydration-scripts.ts +0 -459
- package/src/utils/reachability-analyzer.ts +0 -593
- package/src/utils/react-dom-runtime-interop-plugin.ts +0 -33
- package/src/utils/react-mdx-loader-plugin.ts +0 -63
- package/src/utils/react-runtime-specifier-map.ts +0 -45
- package/src/utils/use-sync-external-store-shim-plugin.ts +0 -45
|
@@ -23,21 +23,24 @@ export interface ReactHydrationAssetServiceConfig {
|
|
|
23
23
|
bundleService: ReactBundleService;
|
|
24
24
|
hmrPageMetadataCache?: ReactHmrPageMetadataCache;
|
|
25
25
|
}
|
|
26
|
+
export declare function getReactIslandComponentKey(componentFile: string, config?: EcoComponentConfig): string;
|
|
26
27
|
/**
|
|
27
28
|
* Manages the creation of client-side hydration assets for React pages and component islands.
|
|
28
29
|
*/
|
|
29
30
|
export declare class ReactHydrationAssetService {
|
|
30
31
|
private readonly config;
|
|
31
32
|
constructor(config: ReactHydrationAssetServiceConfig);
|
|
33
|
+
private getIslandBundleName;
|
|
34
|
+
private getIslandHydrationName;
|
|
32
35
|
/**
|
|
33
36
|
* Resolves the import path for the bundled page component.
|
|
34
37
|
* Uses HMR manager for development or constructs static path for production.
|
|
35
38
|
*
|
|
36
39
|
* @param pagePath - Absolute path to the page source file
|
|
37
|
-
* @param
|
|
40
|
+
* @param assetName - Generated asset name
|
|
38
41
|
* @returns The resolved import path for the bundled component
|
|
39
42
|
*/
|
|
40
|
-
resolveAssetImportPath(pagePath: string,
|
|
43
|
+
resolveAssetImportPath(pagePath: string, assetName: string): Promise<string>;
|
|
41
44
|
/**
|
|
42
45
|
* Creates the asset dependencies for a page: the bundled component and hydration script.
|
|
43
46
|
*
|
|
@@ -54,15 +57,13 @@ export declare class ReactHydrationAssetService {
|
|
|
54
57
|
/**
|
|
55
58
|
* Builds client-side assets for a React component island.
|
|
56
59
|
*
|
|
57
|
-
* Includes the bundled component entry and
|
|
60
|
+
* Includes the bundled component entry and a shared hydration bootstrap script.
|
|
58
61
|
*
|
|
59
62
|
* @param componentFile - Absolute path to the component source file
|
|
60
|
-
* @param componentInstanceId - Unique instance ID for DOM targeting
|
|
61
|
-
* @param props - Serialized props for client-side hydration
|
|
62
63
|
* @param config - Optional component config with `__eco` metadata
|
|
63
64
|
* @returns Processed assets ready for injection
|
|
64
65
|
*/
|
|
65
|
-
buildComponentRenderAssets(componentFile: string,
|
|
66
|
+
buildComponentRenderAssets(componentFile: string, config?: EcoComponentConfig): Promise<ProcessedAsset[]>;
|
|
66
67
|
/**
|
|
67
68
|
* Builds all client-side route assets for a page.
|
|
68
69
|
*
|
|
@@ -6,25 +6,34 @@ import {
|
|
|
6
6
|
} from "@ecopages/core/services/asset-processing-service";
|
|
7
7
|
import { createHydrationScript, createIslandHydrationScript } from "../utils/hydration-scripts.js";
|
|
8
8
|
import { collectDeclaredModulesInConfig } from "../utils/declared-modules.js";
|
|
9
|
+
function getReactIslandComponentKey(componentFile, config) {
|
|
10
|
+
return rapidhash(`${componentFile}:${config?.__eco?.id ?? ""}`).toString();
|
|
11
|
+
}
|
|
9
12
|
class ReactHydrationAssetService {
|
|
10
13
|
config;
|
|
11
14
|
constructor(config) {
|
|
12
15
|
this.config = config;
|
|
13
16
|
}
|
|
17
|
+
getIslandBundleName(componentFile) {
|
|
18
|
+
return `ecopages-react-island-${rapidhash(componentFile)}`;
|
|
19
|
+
}
|
|
20
|
+
getIslandHydrationName(bundleName, componentKey) {
|
|
21
|
+
return `${bundleName}-hydration-${componentKey}`;
|
|
22
|
+
}
|
|
14
23
|
/**
|
|
15
24
|
* Resolves the import path for the bundled page component.
|
|
16
25
|
* Uses HMR manager for development or constructs static path for production.
|
|
17
26
|
*
|
|
18
27
|
* @param pagePath - Absolute path to the page source file
|
|
19
|
-
* @param
|
|
28
|
+
* @param assetName - Generated asset name
|
|
20
29
|
* @returns The resolved import path for the bundled component
|
|
21
30
|
*/
|
|
22
|
-
async resolveAssetImportPath(pagePath,
|
|
31
|
+
async resolveAssetImportPath(pagePath, assetName) {
|
|
23
32
|
const hmrManager = this.config.assetProcessingService?.getHmrManager();
|
|
24
33
|
if (hmrManager?.isEnabled()) {
|
|
25
34
|
return hmrManager.registerEntrypoint(pagePath);
|
|
26
35
|
}
|
|
27
|
-
return `/${path.join(RESOLVED_ASSETS_DIR, path.relative(this.config.srcDir, pagePath)).replace(path.basename(pagePath), `${
|
|
36
|
+
return `/${path.join(RESOLVED_ASSETS_DIR, path.relative(this.config.srcDir, pagePath)).replace(path.basename(pagePath), `${assetName}.js`).replace(/\\/g, "/")}`;
|
|
28
37
|
}
|
|
29
38
|
/**
|
|
30
39
|
* Creates the asset dependencies for a page: the bundled component and hydration script.
|
|
@@ -96,19 +105,22 @@ class ReactHydrationAssetService {
|
|
|
96
105
|
/**
|
|
97
106
|
* Builds client-side assets for a React component island.
|
|
98
107
|
*
|
|
99
|
-
* Includes the bundled component entry and
|
|
108
|
+
* Includes the bundled component entry and a shared hydration bootstrap script.
|
|
100
109
|
*
|
|
101
110
|
* @param componentFile - Absolute path to the component source file
|
|
102
|
-
* @param componentInstanceId - Unique instance ID for DOM targeting
|
|
103
|
-
* @param props - Serialized props for client-side hydration
|
|
104
111
|
* @param config - Optional component config with `__eco` metadata
|
|
105
112
|
* @returns Processed assets ready for injection
|
|
106
113
|
*/
|
|
107
|
-
async buildComponentRenderAssets(componentFile,
|
|
108
|
-
const componentName =
|
|
109
|
-
const
|
|
114
|
+
async buildComponentRenderAssets(componentFile, config) {
|
|
115
|
+
const componentName = this.getIslandBundleName(componentFile);
|
|
116
|
+
const componentKey = getReactIslandComponentKey(componentFile, config);
|
|
117
|
+
const hydrationName = this.getIslandHydrationName(componentName, componentKey);
|
|
110
118
|
const hmrManager = this.config.assetProcessingService?.getHmrManager();
|
|
111
119
|
const isDevelopment = hmrManager?.isEnabled() ?? false;
|
|
120
|
+
if (isDevelopment) {
|
|
121
|
+
this.config.hmrPageMetadataCache?.markOwnedEntrypoint(componentFile);
|
|
122
|
+
}
|
|
123
|
+
const importPath = await this.resolveAssetImportPath(componentFile, componentName);
|
|
112
124
|
const declaredModules = collectDeclaredModulesInConfig(config);
|
|
113
125
|
const bundleOptions = await this.config.bundleService.createBundleOptions(
|
|
114
126
|
componentName,
|
|
@@ -136,19 +148,18 @@ class ReactHydrationAssetService {
|
|
|
136
148
|
importPath,
|
|
137
149
|
reactImportPath: runtimeImports.react,
|
|
138
150
|
reactDomClientImportPath: runtimeImports.reactDomClient,
|
|
139
|
-
targetSelector: `[data-eco-component-
|
|
140
|
-
props,
|
|
151
|
+
targetSelector: `[data-eco-component-key="${componentKey}"]`,
|
|
141
152
|
componentRef: config?.__eco?.id,
|
|
142
153
|
componentFile,
|
|
143
154
|
isDevelopment
|
|
144
155
|
}),
|
|
145
|
-
name:
|
|
156
|
+
name: hydrationName,
|
|
146
157
|
bundle: false,
|
|
147
158
|
attributes: {
|
|
148
159
|
type: "module",
|
|
149
160
|
defer: "",
|
|
150
161
|
"data-eco-rerun": "true",
|
|
151
|
-
"data-eco-script-id":
|
|
162
|
+
"data-eco-script-id": hydrationName,
|
|
152
163
|
"data-eco-persist": "true"
|
|
153
164
|
}
|
|
154
165
|
})
|
|
@@ -194,5 +205,6 @@ class ReactHydrationAssetService {
|
|
|
194
205
|
}
|
|
195
206
|
}
|
|
196
207
|
export {
|
|
197
|
-
ReactHydrationAssetService
|
|
208
|
+
ReactHydrationAssetService,
|
|
209
|
+
getReactIslandComponentKey
|
|
198
210
|
};
|
|
@@ -42,7 +42,7 @@ class ReactPageModuleService {
|
|
|
42
42
|
entrypoints: [filePath],
|
|
43
43
|
root: this.config.rootDir,
|
|
44
44
|
outdir,
|
|
45
|
-
target: "
|
|
45
|
+
target: "es2022",
|
|
46
46
|
format: "esm",
|
|
47
47
|
sourcemap: "none",
|
|
48
48
|
splitting: false,
|
|
@@ -62,7 +62,10 @@ class ReactPageModuleService {
|
|
|
62
62
|
if (!compiledOutput) {
|
|
63
63
|
throw new Error(`No compiled MDX output generated for page: ${filePath}`);
|
|
64
64
|
}
|
|
65
|
-
return await import(
|
|
65
|
+
return await import(
|
|
66
|
+
/* @vite-ignore */
|
|
67
|
+
pathToFileURL(compiledOutput).href
|
|
68
|
+
);
|
|
66
69
|
}
|
|
67
70
|
/**
|
|
68
71
|
* Ensures that an EcoComponentConfig has proper `__eco` metadata attached.
|
|
@@ -19,11 +19,13 @@ export type ReactRuntimeImports = {
|
|
|
19
19
|
};
|
|
20
20
|
export interface ReactRuntimeBundleServiceConfig {
|
|
21
21
|
routerAdapter?: ReactRouterAdapter;
|
|
22
|
+
rootDir?: string;
|
|
22
23
|
}
|
|
23
24
|
type RuntimeMode = 'development' | 'production';
|
|
24
25
|
export declare class ReactRuntimeBundleService {
|
|
25
26
|
private readonly config;
|
|
26
27
|
constructor(config: ReactRuntimeBundleServiceConfig);
|
|
28
|
+
setRootDir(rootDir: string | undefined): void;
|
|
27
29
|
private get isDevelopment();
|
|
28
30
|
private getCurrentRuntimeMode;
|
|
29
31
|
private createRuntimeDefines;
|
|
@@ -11,6 +11,9 @@ class ReactRuntimeBundleService {
|
|
|
11
11
|
constructor(config) {
|
|
12
12
|
this.config = config;
|
|
13
13
|
}
|
|
14
|
+
setRootDir(rootDir) {
|
|
15
|
+
this.config.rootDir = rootDir;
|
|
16
|
+
}
|
|
14
17
|
get isDevelopment() {
|
|
15
18
|
return process.env.NODE_ENV === "development";
|
|
16
19
|
}
|
|
@@ -79,6 +82,7 @@ class ReactRuntimeBundleService {
|
|
|
79
82
|
name: "react",
|
|
80
83
|
fileName: this.getReactVendorFileName(mode),
|
|
81
84
|
cacheDirName: `ecopages-react-runtime-${mode}`,
|
|
85
|
+
rootDir: this.config.rootDir,
|
|
82
86
|
bundleOptions: {
|
|
83
87
|
define: this.createRuntimeDefines(mode)
|
|
84
88
|
}
|
|
@@ -88,6 +92,7 @@ class ReactRuntimeBundleService {
|
|
|
88
92
|
name: "react-dom",
|
|
89
93
|
fileName: this.getReactDomVendorFileName(mode),
|
|
90
94
|
cacheDirName: `ecopages-react-runtime-${mode}`,
|
|
95
|
+
rootDir: this.config.rootDir,
|
|
91
96
|
bundleOptions: {
|
|
92
97
|
define: this.createRuntimeDefines(mode),
|
|
93
98
|
plugins: reactDomBundlePlugins
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { dirname, extname, resolve } from "node:path";
|
|
3
3
|
import { parseSync } from "oxc-parser";
|
|
4
|
-
import { analyzeReachability } from "./reachability-analyzer";
|
|
4
|
+
import { analyzeReachability } from "./reachability-analyzer.js";
|
|
5
5
|
const SOURCE_FILE_FILTER = /\.(tsx?|jsx?)$/;
|
|
6
6
|
const SERVER_ONLY_ECO_PAGE_OPTION_KEYS = /* @__PURE__ */ new Set([
|
|
7
7
|
"cache",
|
|
@@ -484,7 +484,7 @@ function createClientGraphBoundaryPlugin(options) {
|
|
|
484
484
|
}
|
|
485
485
|
if (!modified) return void 0;
|
|
486
486
|
const ext = extname(args.path).slice(1);
|
|
487
|
-
return { contents: transformed, loader: ext };
|
|
487
|
+
return { contents: transformed, loader: ext, resolveDir: dirname(args.path) };
|
|
488
488
|
});
|
|
489
489
|
}
|
|
490
490
|
};
|
|
@@ -41,7 +41,10 @@ function collectPageDeclaredModulesFromModule(pageModule) {
|
|
|
41
41
|
}
|
|
42
42
|
async function collectPageDeclaredModules(pagePath) {
|
|
43
43
|
try {
|
|
44
|
-
const pageModule = await import(
|
|
44
|
+
const pageModule = await import(
|
|
45
|
+
/* @vite-ignore */
|
|
46
|
+
pagePath
|
|
47
|
+
);
|
|
45
48
|
return collectPageDeclaredModulesFromModule(pageModule);
|
|
46
49
|
} catch {
|
|
47
50
|
return [];
|
|
@@ -30,10 +30,8 @@ export type IslandHydrationScriptOptions = {
|
|
|
30
30
|
reactImportPath: string;
|
|
31
31
|
/** Browser import path for react-dom/client runtime. */
|
|
32
32
|
reactDomClientImportPath: string;
|
|
33
|
-
/** Selector that resolves to
|
|
33
|
+
/** Selector that resolves to all SSR root elements for this island component. */
|
|
34
34
|
targetSelector: string;
|
|
35
|
-
/** Serialized component props emitted at render time. */
|
|
36
|
-
props: Record<string, unknown>;
|
|
37
35
|
/** Optional stable component id used to resolve named exports reliably. */
|
|
38
36
|
componentRef?: string;
|
|
39
37
|
/** Optional source file hint used as fallback for component resolution. */
|
|
@@ -31,16 +31,19 @@ function getProdPageRootCleanupScript() {
|
|
|
31
31
|
return 'window.__ECO_PAGES__=window.__ECO_PAGES__||{};window.__ECO_PAGES__.react=window.__ECO_PAGES__.react||{};window.__ECO_PAGES__.react.cleanupPageRoot=()=>{const a=window.__ECO_PAGES__.react?.pageRoot||root;if(!a){window.__ECO_PAGES__.react.pageRoot=null;window.__ECO_PAGES__?.navigation?.releaseOwnership?.("react-router");delete window.__ECO_PAGES__.page;return}window.__ECO_PAGES__.react.pageRoot=null;window.__ECO_PAGES__?.navigation?.releaseOwnership?.("react-router");delete window.__ECO_PAGES__.page;root=null;a.unmount()};';
|
|
32
32
|
}
|
|
33
33
|
function getDevRouterBootstrapRegistrationScript() {
|
|
34
|
-
return `window.__ECO_PAGES__?.navigation?.
|
|
34
|
+
return `const currentOwnerState = window.__ECO_PAGES__?.navigation?.getOwnerState?.();
|
|
35
|
+
if (!(currentOwnerState?.owner === "react-router" && currentOwnerState.canHandleSpaNavigation)) {
|
|
36
|
+
window.__ECO_PAGES__?.navigation?.register({
|
|
35
37
|
owner: "react-router",
|
|
36
38
|
cleanupBeforeHandoff: async () => {
|
|
37
39
|
window.__ECO_PAGES__?.react?.cleanupPageRoot?.();
|
|
38
40
|
}
|
|
39
41
|
});
|
|
40
|
-
window.__ECO_PAGES__?.navigation?.claimOwnership?.("react-router")
|
|
42
|
+
window.__ECO_PAGES__?.navigation?.claimOwnership?.("react-router");
|
|
43
|
+
}`;
|
|
41
44
|
}
|
|
42
45
|
function getProdRouterBootstrapRegistrationScript() {
|
|
43
|
-
return 'window.__ECO_PAGES__?.navigation?.register({owner:"react-router",cleanupBeforeHandoff:async()=>{window.__ECO_PAGES__?.react?.cleanupPageRoot?.()}});window.__ECO_PAGES__?.navigation?.claimOwnership?.("react-router")
|
|
46
|
+
return 'const o=window.__ECO_PAGES__?.navigation?.getOwnerState?.();if(!(o?.owner==="react-router"&&o.canHandleSpaNavigation)){window.__ECO_PAGES__?.navigation?.register({owner:"react-router",cleanupBeforeHandoff:async()=>{window.__ECO_PAGES__?.react?.cleanupPageRoot?.()}});window.__ECO_PAGES__?.navigation?.claimOwnership?.("react-router")}';
|
|
44
47
|
}
|
|
45
48
|
function createDevScriptWithRouter(options) {
|
|
46
49
|
const { importPath, isMdx, router, reactImportPath, reactDomClientImportPath, routerImportPath } = options;
|
|
@@ -93,16 +96,20 @@ const mount = () => {
|
|
|
93
96
|
window.__ECO_PAGES__.react.pageRoot = root;
|
|
94
97
|
}
|
|
95
98
|
window.__ECO_PAGES__.hmrHandlers["${importPath}"] = async (newUrl) => {
|
|
96
|
-
if (window.__ECO_PAGES__?.navigation?.getOwnerState().owner === "react-router") {
|
|
97
|
-
await window.__ECO_PAGES__?.navigation?.reloadCurrentPage?.({ clearCache: false, source: "react-router" });
|
|
98
|
-
console.log("[ecopages] ${getComponentType(isMdx)} component updated via router");
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
99
|
try {
|
|
102
100
|
const newModule = await import(newUrl);
|
|
101
|
+
const nextProps = getPageData();
|
|
103
102
|
${getHmrImportStatement(isMdx)}
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
window.__ECO_PAGES__.page = {
|
|
104
|
+
module: "${importPath}",
|
|
105
|
+
props: nextProps
|
|
106
|
+
};
|
|
107
|
+
root.render(createTree(NewPage, nextProps));
|
|
108
|
+
if (window.__ECO_PAGES__?.navigation?.getOwnerState().owner === "react-router") {
|
|
109
|
+
console.log("[ecopages] ${getComponentType(isMdx)} component updated via router");
|
|
110
|
+
} else {
|
|
111
|
+
console.log("[ecopages] ${getComponentType(isMdx)} component updated");
|
|
112
|
+
}
|
|
106
113
|
} catch (e) {
|
|
107
114
|
console.error("[ecopages] Failed to hot-reload ${getComponentType(isMdx)} component:", e);
|
|
108
115
|
}
|
|
@@ -245,17 +252,22 @@ const resolveComponent = () => {
|
|
|
245
252
|
};
|
|
246
253
|
|
|
247
254
|
const mount = () => {
|
|
248
|
-
const
|
|
255
|
+
const targets = document.querySelectorAll(${targetSelector});
|
|
249
256
|
const Component = resolveComponent();
|
|
250
|
-
if (!
|
|
257
|
+
if (!Component || targets.length === 0) {
|
|
251
258
|
return;
|
|
252
259
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
260
|
+
targets.forEach((target) => {
|
|
261
|
+
if (!(target instanceof HTMLElement)) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const props = JSON.parse(atob(target.getAttribute("data-eco-props") || "e30="));
|
|
265
|
+
const container = document.createElement("eco-island");
|
|
266
|
+
container.style.display = "block";
|
|
267
|
+
target.replaceWith(container);
|
|
268
|
+
const root = createRoot(container);
|
|
269
|
+
root.render(createElement(Component, props));
|
|
270
|
+
});
|
|
259
271
|
};
|
|
260
272
|
|
|
261
273
|
if (document.readyState === "loading") {
|
|
@@ -265,7 +277,7 @@ if (document.readyState === "loading") {
|
|
|
265
277
|
}
|
|
266
278
|
`.trim();
|
|
267
279
|
}
|
|
268
|
-
return `import{createRoot as cr}from"${options.reactDomClientImportPath}";import{createElement as ce}from"${options.reactImportPath}";import*as M from"${options.importPath}";const r=${componentRef};const f=${componentFile};const mv=Object.values(M);const c=mv.find((e)=>{if(typeof e!=="function")return false;const ec=e.config?.__eco;if(!ec)return false;if(r&&ec.id===r)return true;if(f&&ec.file===f)return true;return false;})??(typeof M.default==="function"?M.default:mv.find((e)=>typeof e==="function")??null);const m=()=>{const
|
|
280
|
+
return `import{createRoot as cr}from"${options.reactDomClientImportPath}";import{createElement as ce}from"${options.reactImportPath}";import*as M from"${options.importPath}";const r=${componentRef};const f=${componentFile};const mv=Object.values(M);const c=mv.find((e)=>{if(typeof e!=="function")return false;const ec=e.config?.__eco;if(!ec)return false;if(r&&ec.id===r)return true;if(f&&ec.file===f)return true;return false;})??(typeof M.default==="function"?M.default:mv.find((e)=>typeof e==="function")??null);const m=()=>{const ts=document.querySelectorAll(${targetSelector});if(!c||ts.length===0)return;ts.forEach((t)=>{if(!(t instanceof HTMLElement))return;const p=JSON.parse(atob(t.getAttribute("data-eco-props")||"e30="));const ct=document.createElement("eco-island");ct.style.display="block";t.replaceWith(ct);cr(ct).render(ce(c,p))})};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",m,{once:true}):m()`;
|
|
269
281
|
}
|
|
270
282
|
export {
|
|
271
283
|
createHydrationScript,
|