@kaena1/ecomm-contained-utils 1.0.0
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 +681 -0
- package/dist/client.d.ts +94 -0
- package/dist/client.js +10 -0
- package/dist/components/ImportMapScripts.js +33 -0
- package/dist/components/RemoteLinks.js +8 -0
- package/dist/components/RemoteRenderer.js +26 -0
- package/dist/hooks/useRemoteComponent.js +61 -0
- package/dist/index.d.ts +127 -0
- package/dist/index.js +18 -0
- package/dist/package.json.js +10 -0
- package/dist/server.d.ts +66 -0
- package/dist/server.js +11 -0
- package/dist/services/ImportMapService.js +40 -0
- package/dist/services/fetchManifest.js +26 -0
- package/dist/services/moduleLoader.js +120 -0
- package/package.json +75 -0
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { default as default_2 } from 'react';
|
|
2
|
+
|
|
3
|
+
declare interface ComponentManifest {
|
|
4
|
+
bundleUrl: string;
|
|
5
|
+
styleUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export declare class ModuleLoader {
|
|
9
|
+
private loadedModules;
|
|
10
|
+
private importMapInjected;
|
|
11
|
+
private prepareGlobalDependencies;
|
|
12
|
+
/**
|
|
13
|
+
* Ensure import map is injected before loading any modules
|
|
14
|
+
* Import maps MUST be added before any module scripts
|
|
15
|
+
*/
|
|
16
|
+
private ensureImportMap;
|
|
17
|
+
/**
|
|
18
|
+
* Load remote React component from ES module URL
|
|
19
|
+
*
|
|
20
|
+
* @param options - Configuration object with bundleUrl and componentName
|
|
21
|
+
* @returns Promise that resolves to the loaded React component
|
|
22
|
+
* @throws Error if component loading fails or times out (10s)
|
|
23
|
+
*/
|
|
24
|
+
loadComponent(options: ModuleLoadOptions): Promise<RemoteComponentType>;
|
|
25
|
+
/**
|
|
26
|
+
* Load ES module from external URL using dynamic script injection
|
|
27
|
+
* This bypasses Webpack's module resolution and works with import maps
|
|
28
|
+
*/
|
|
29
|
+
private loadModuleViaScript;
|
|
30
|
+
/**
|
|
31
|
+
* Preload a module without extracting components
|
|
32
|
+
* Useful for warming up cache
|
|
33
|
+
*
|
|
34
|
+
* @param bundleUrl - URL of the module to preload
|
|
35
|
+
*/
|
|
36
|
+
preloadModule(bundleUrl: string): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Check if a module has already been loaded
|
|
39
|
+
*
|
|
40
|
+
* @param bundleUrl - URL of the module to check
|
|
41
|
+
* @returns true if module is already loaded, false otherwise
|
|
42
|
+
*/
|
|
43
|
+
isLoaded(bundleUrl: string): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Clear all loaded modules from cache
|
|
46
|
+
* Useful for development/testing
|
|
47
|
+
*/
|
|
48
|
+
clearCache(): void;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export declare const moduleLoader: ModuleLoader;
|
|
52
|
+
|
|
53
|
+
declare interface ModuleLoadOptions {
|
|
54
|
+
bundleUrl: string;
|
|
55
|
+
componentName: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
declare interface RemoteComponentState {
|
|
59
|
+
component: RemoteComponentType | null;
|
|
60
|
+
manifest: ComponentManifest | null;
|
|
61
|
+
loading: boolean;
|
|
62
|
+
error: string | null;
|
|
63
|
+
loaded: boolean;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
declare type RemoteComponentType = React.ComponentType<any>;
|
|
67
|
+
|
|
68
|
+
export declare const RemoteRenderer: default_2.FC<RemoteRendererProps>;
|
|
69
|
+
|
|
70
|
+
declare interface RemoteRendererProps {
|
|
71
|
+
manifest: ComponentManifest;
|
|
72
|
+
componentName: string;
|
|
73
|
+
componentProps?: any;
|
|
74
|
+
autoLoad?: boolean;
|
|
75
|
+
placeholder?: default_2.ReactNode;
|
|
76
|
+
children?: default_2.ReactNode;
|
|
77
|
+
errorFallback?: (error: string) => default_2.ReactNode;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export declare function useRemoteComponent(options: UseRemoteComponentOptions): UseRemoteComponentReturn;
|
|
81
|
+
|
|
82
|
+
declare interface UseRemoteComponentOptions {
|
|
83
|
+
manifest: ComponentManifest;
|
|
84
|
+
componentName: string;
|
|
85
|
+
autoLoad?: boolean;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
declare interface UseRemoteComponentReturn extends RemoteComponentState {
|
|
89
|
+
loadComponent: () => Promise<void>;
|
|
90
|
+
reload: () => Promise<void>;
|
|
91
|
+
clearError: () => void;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { }
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRemoteComponent as r } from "./hooks/useRemoteComponent.js";
|
|
3
|
+
import { RemoteRenderer as t } from "./components/RemoteRenderer.js";
|
|
4
|
+
import { ModuleLoader as n, moduleLoader as p } from "./services/moduleLoader.js";
|
|
5
|
+
export {
|
|
6
|
+
n as ModuleLoader,
|
|
7
|
+
t as RemoteRenderer,
|
|
8
|
+
p as moduleLoader,
|
|
9
|
+
r as useRemoteComponent
|
|
10
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsxs as e, Fragment as r, jsx as s } from "react/jsx-runtime";
|
|
2
|
+
import { generateImportMapJson as t } from "../services/ImportMapService.js";
|
|
3
|
+
const m = () => /* @__PURE__ */ e(r, { children: [
|
|
4
|
+
/* @__PURE__ */ s(
|
|
5
|
+
"script",
|
|
6
|
+
{
|
|
7
|
+
defer: !0,
|
|
8
|
+
src: "https://ga.jspm.io/npm:es-module-shims@1.10.0/dist/es-module-shims.js",
|
|
9
|
+
crossOrigin: "anonymous"
|
|
10
|
+
}
|
|
11
|
+
),
|
|
12
|
+
/* @__PURE__ */ s(
|
|
13
|
+
"link",
|
|
14
|
+
{
|
|
15
|
+
rel: "preconnect",
|
|
16
|
+
href: "https://assets-qa.mintmobile.com",
|
|
17
|
+
crossOrigin: "anonymous"
|
|
18
|
+
}
|
|
19
|
+
),
|
|
20
|
+
/* @__PURE__ */ s("link", { rel: "dns-prefetch", href: "https://assets-qa.mintmobile.com" }),
|
|
21
|
+
/* @__PURE__ */ s("link", { rel: "preconnect", href: "https://esm.sh", crossOrigin: "anonymous" }),
|
|
22
|
+
/* @__PURE__ */ s("link", { rel: "dns-prefetch", href: "https://esm.sh" }),
|
|
23
|
+
/* @__PURE__ */ s(
|
|
24
|
+
"script",
|
|
25
|
+
{
|
|
26
|
+
type: "importmap-shim",
|
|
27
|
+
dangerouslySetInnerHTML: { __html: t() }
|
|
28
|
+
}
|
|
29
|
+
)
|
|
30
|
+
] });
|
|
31
|
+
export {
|
|
32
|
+
m as ImportMapScripts
|
|
33
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsxs as l, Fragment as t, jsx as r } from "react/jsx-runtime";
|
|
2
|
+
const s = ({ manifest: e }) => /* @__PURE__ */ l(t, { children: [
|
|
3
|
+
e.styleUrl && /* @__PURE__ */ r("link", { rel: "stylesheet", href: e.styleUrl }),
|
|
4
|
+
/* @__PURE__ */ r("link", { rel: "modulepreload", href: e.bundleUrl })
|
|
5
|
+
] });
|
|
6
|
+
export {
|
|
7
|
+
s as RemoteLinks
|
|
8
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as o, Fragment as c } from "react/jsx-runtime";
|
|
3
|
+
import { useRemoteComponent as d } from "../hooks/useRemoteComponent.js";
|
|
4
|
+
const x = ({
|
|
5
|
+
manifest: t,
|
|
6
|
+
componentName: m,
|
|
7
|
+
componentProps: u,
|
|
8
|
+
autoLoad: i = !0,
|
|
9
|
+
placeholder: p = null,
|
|
10
|
+
children: l,
|
|
11
|
+
errorFallback: e
|
|
12
|
+
}) => {
|
|
13
|
+
const {
|
|
14
|
+
component: r,
|
|
15
|
+
error: n,
|
|
16
|
+
loaded: s
|
|
17
|
+
} = d({
|
|
18
|
+
manifest: t,
|
|
19
|
+
componentName: m,
|
|
20
|
+
autoLoad: i
|
|
21
|
+
});
|
|
22
|
+
return n ? e ? e(n) : null : !s || !r ? /* @__PURE__ */ o(c, { children: p }) : /* @__PURE__ */ o(r, { ...u, children: l });
|
|
23
|
+
};
|
|
24
|
+
export {
|
|
25
|
+
x as RemoteRenderer
|
|
26
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState as f, useCallback as l, useEffect as p } from "react";
|
|
3
|
+
import { moduleLoader as g } from "../services/moduleLoader.js";
|
|
4
|
+
function b(d) {
|
|
5
|
+
const {
|
|
6
|
+
manifest: t,
|
|
7
|
+
componentName: s,
|
|
8
|
+
autoLoad: c = !0
|
|
9
|
+
} = d, [m, e] = f({
|
|
10
|
+
component: null,
|
|
11
|
+
manifest: null,
|
|
12
|
+
loading: !1,
|
|
13
|
+
error: null,
|
|
14
|
+
loaded: !1
|
|
15
|
+
}), n = l(async () => {
|
|
16
|
+
try {
|
|
17
|
+
e((r) => ({
|
|
18
|
+
...r,
|
|
19
|
+
loading: !0,
|
|
20
|
+
error: null,
|
|
21
|
+
manifest: t
|
|
22
|
+
}));
|
|
23
|
+
const o = {
|
|
24
|
+
bundleUrl: t.bundleUrl,
|
|
25
|
+
componentName: s
|
|
26
|
+
}, a = await g.loadComponent(o);
|
|
27
|
+
e((r) => ({
|
|
28
|
+
...r,
|
|
29
|
+
component: a,
|
|
30
|
+
loading: !1,
|
|
31
|
+
loaded: !0
|
|
32
|
+
}));
|
|
33
|
+
} catch (o) {
|
|
34
|
+
console.error("Error loading remote component:", o);
|
|
35
|
+
const a = o instanceof Error ? o.message : "Unknown error loading component";
|
|
36
|
+
e((r) => ({
|
|
37
|
+
...r,
|
|
38
|
+
error: a,
|
|
39
|
+
loading: !1,
|
|
40
|
+
loaded: !1
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
}, [t, s]), u = l(async () => {
|
|
44
|
+
await n();
|
|
45
|
+
}, [n]), i = l(() => {
|
|
46
|
+
e((o) => ({ ...o, error: null }));
|
|
47
|
+
}, []);
|
|
48
|
+
return p(() => {
|
|
49
|
+
c && n().then(() => {
|
|
50
|
+
e((o) => ({ ...o, loaded: !0 }));
|
|
51
|
+
});
|
|
52
|
+
}, [c, n]), {
|
|
53
|
+
...m,
|
|
54
|
+
loadComponent: n,
|
|
55
|
+
reload: u,
|
|
56
|
+
clearError: i
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export {
|
|
60
|
+
b as useRemoteComponent
|
|
61
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
|
|
3
|
+
import { default as default_2 } from 'react';
|
|
4
|
+
|
|
5
|
+
export declare interface ComponentManifest {
|
|
6
|
+
bundleUrl: string;
|
|
7
|
+
styleUrl?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export declare function fetchManifest(manifestUrl: string): Promise<RemoteManifest>;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Generate complete import map object for remote components
|
|
14
|
+
*
|
|
15
|
+
* @param config - Optional configuration to override default settings
|
|
16
|
+
* @returns Import map object ready for browser consumption
|
|
17
|
+
*/
|
|
18
|
+
export declare const generateImportMap: (config?: ImportMapConfig) => object;
|
|
19
|
+
|
|
20
|
+
export declare const generateImportMapJson: (config?: ImportMapConfig) => string;
|
|
21
|
+
|
|
22
|
+
export declare interface ImportMapConfig {
|
|
23
|
+
reactVersion?: string;
|
|
24
|
+
reactDomVersion?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export declare const ImportMapScripts: () => JSX.Element;
|
|
28
|
+
|
|
29
|
+
export declare class ModuleLoader {
|
|
30
|
+
private loadedModules;
|
|
31
|
+
private importMapInjected;
|
|
32
|
+
private prepareGlobalDependencies;
|
|
33
|
+
/**
|
|
34
|
+
* Ensure import map is injected before loading any modules
|
|
35
|
+
* Import maps MUST be added before any module scripts
|
|
36
|
+
*/
|
|
37
|
+
private ensureImportMap;
|
|
38
|
+
/**
|
|
39
|
+
* Load remote React component from ES module URL
|
|
40
|
+
*
|
|
41
|
+
* @param options - Configuration object with bundleUrl and componentName
|
|
42
|
+
* @returns Promise that resolves to the loaded React component
|
|
43
|
+
* @throws Error if component loading fails or times out (10s)
|
|
44
|
+
*/
|
|
45
|
+
loadComponent(options: ModuleLoadOptions): Promise<RemoteComponentType>;
|
|
46
|
+
/**
|
|
47
|
+
* Load ES module from external URL using dynamic script injection
|
|
48
|
+
* This bypasses Webpack's module resolution and works with import maps
|
|
49
|
+
*/
|
|
50
|
+
private loadModuleViaScript;
|
|
51
|
+
/**
|
|
52
|
+
* Preload a module without extracting components
|
|
53
|
+
* Useful for warming up cache
|
|
54
|
+
*
|
|
55
|
+
* @param bundleUrl - URL of the module to preload
|
|
56
|
+
*/
|
|
57
|
+
preloadModule(bundleUrl: string): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Check if a module has already been loaded
|
|
60
|
+
*
|
|
61
|
+
* @param bundleUrl - URL of the module to check
|
|
62
|
+
* @returns true if module is already loaded, false otherwise
|
|
63
|
+
*/
|
|
64
|
+
isLoaded(bundleUrl: string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Clear all loaded modules from cache
|
|
67
|
+
* Useful for development/testing
|
|
68
|
+
*/
|
|
69
|
+
clearCache(): void;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export declare const moduleLoader: ModuleLoader;
|
|
73
|
+
|
|
74
|
+
export declare interface ModuleLoadOptions {
|
|
75
|
+
bundleUrl: string;
|
|
76
|
+
componentName: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export declare interface RemoteComponentState {
|
|
80
|
+
component: RemoteComponentType | null;
|
|
81
|
+
manifest: ComponentManifest | null;
|
|
82
|
+
loading: boolean;
|
|
83
|
+
error: string | null;
|
|
84
|
+
loaded: boolean;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export declare type RemoteComponentType = React.ComponentType<any>;
|
|
88
|
+
|
|
89
|
+
export declare const RemoteLinks: ({ manifest }: RemoteLinksProps) => JSX.Element;
|
|
90
|
+
|
|
91
|
+
declare interface RemoteLinksProps {
|
|
92
|
+
manifest: ComponentManifest;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export declare interface RemoteManifest {
|
|
96
|
+
components: Record<string, ComponentManifest>;
|
|
97
|
+
version: string;
|
|
98
|
+
generatedAt: string;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export declare const RemoteRenderer: default_2.FC<RemoteRendererProps>;
|
|
102
|
+
|
|
103
|
+
declare interface RemoteRendererProps {
|
|
104
|
+
manifest: ComponentManifest;
|
|
105
|
+
componentName: string;
|
|
106
|
+
componentProps?: any;
|
|
107
|
+
autoLoad?: boolean;
|
|
108
|
+
placeholder?: default_2.ReactNode;
|
|
109
|
+
children?: default_2.ReactNode;
|
|
110
|
+
errorFallback?: (error: string) => default_2.ReactNode;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export declare function useRemoteComponent(options: UseRemoteComponentOptions): UseRemoteComponentReturn;
|
|
114
|
+
|
|
115
|
+
export declare interface UseRemoteComponentOptions {
|
|
116
|
+
manifest: ComponentManifest;
|
|
117
|
+
componentName: string;
|
|
118
|
+
autoLoad?: boolean;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export declare interface UseRemoteComponentReturn extends RemoteComponentState {
|
|
122
|
+
loadComponent: () => Promise<void>;
|
|
123
|
+
reload: () => Promise<void>;
|
|
124
|
+
clearError: () => void;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export { }
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { fetchManifest as r } from "./services/fetchManifest.js";
|
|
2
|
+
import { ModuleLoader as m, moduleLoader as p } from "./services/moduleLoader.js";
|
|
3
|
+
import { generateImportMap as a, generateImportMapJson as n } from "./services/ImportMapService.js";
|
|
4
|
+
import { useRemoteComponent as d } from "./hooks/useRemoteComponent.js";
|
|
5
|
+
import { RemoteRenderer as M } from "./components/RemoteRenderer.js";
|
|
6
|
+
import { RemoteLinks as i } from "./components/RemoteLinks.js";
|
|
7
|
+
import { ImportMapScripts as I } from "./components/ImportMapScripts.js";
|
|
8
|
+
export {
|
|
9
|
+
I as ImportMapScripts,
|
|
10
|
+
m as ModuleLoader,
|
|
11
|
+
i as RemoteLinks,
|
|
12
|
+
M as RemoteRenderer,
|
|
13
|
+
r as fetchManifest,
|
|
14
|
+
a as generateImportMap,
|
|
15
|
+
n as generateImportMapJson,
|
|
16
|
+
p as moduleLoader,
|
|
17
|
+
d as useRemoteComponent
|
|
18
|
+
};
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
|
|
3
|
+
export declare interface ComponentManifest {
|
|
4
|
+
bundleUrl: string;
|
|
5
|
+
styleUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export declare function fetchManifest(manifestUrl: string): Promise<RemoteManifest>;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Generate complete import map object for remote components
|
|
12
|
+
*
|
|
13
|
+
* @param config - Optional configuration to override default settings
|
|
14
|
+
* @returns Import map object ready for browser consumption
|
|
15
|
+
*/
|
|
16
|
+
export declare const generateImportMap: (config?: ImportMapConfig) => object;
|
|
17
|
+
|
|
18
|
+
export declare const generateImportMapJson: (config?: ImportMapConfig) => string;
|
|
19
|
+
|
|
20
|
+
export declare interface ImportMapConfig {
|
|
21
|
+
reactVersion?: string;
|
|
22
|
+
reactDomVersion?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export declare const ImportMapScripts: () => JSX.Element;
|
|
26
|
+
|
|
27
|
+
export declare interface ModuleLoadOptions {
|
|
28
|
+
bundleUrl: string;
|
|
29
|
+
componentName: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export declare interface RemoteComponentState {
|
|
33
|
+
component: RemoteComponentType | null;
|
|
34
|
+
manifest: ComponentManifest | null;
|
|
35
|
+
loading: boolean;
|
|
36
|
+
error: string | null;
|
|
37
|
+
loaded: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export declare type RemoteComponentType = React.ComponentType<any>;
|
|
41
|
+
|
|
42
|
+
export declare const RemoteLinks: ({ manifest }: RemoteLinksProps) => JSX.Element;
|
|
43
|
+
|
|
44
|
+
declare interface RemoteLinksProps {
|
|
45
|
+
manifest: ComponentManifest;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export declare interface RemoteManifest {
|
|
49
|
+
components: Record<string, ComponentManifest>;
|
|
50
|
+
version: string;
|
|
51
|
+
generatedAt: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export declare interface UseRemoteComponentOptions {
|
|
55
|
+
manifest: ComponentManifest;
|
|
56
|
+
componentName: string;
|
|
57
|
+
autoLoad?: boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export declare interface UseRemoteComponentReturn extends RemoteComponentState {
|
|
61
|
+
loadComponent: () => Promise<void>;
|
|
62
|
+
reload: () => Promise<void>;
|
|
63
|
+
clearError: () => void;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { }
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { fetchManifest as o } from "./services/fetchManifest.js";
|
|
2
|
+
import { generateImportMap as p, generateImportMapJson as m } from "./services/ImportMapService.js";
|
|
3
|
+
import { ImportMapScripts as f } from "./components/ImportMapScripts.js";
|
|
4
|
+
import { RemoteLinks as s } from "./components/RemoteLinks.js";
|
|
5
|
+
export {
|
|
6
|
+
f as ImportMapScripts,
|
|
7
|
+
s as RemoteLinks,
|
|
8
|
+
o as fetchManifest,
|
|
9
|
+
p as generateImportMap,
|
|
10
|
+
m as generateImportMapJson
|
|
11
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import n from "../package.json.js";
|
|
2
|
+
const s = (e) => e.replace(/^[\^~]/, ""), a = {
|
|
3
|
+
reactVersion: s(n.peerDependencies.react),
|
|
4
|
+
reactDomVersion: s(n.peerDependencies["react-dom"])
|
|
5
|
+
}, c = () => `data:text/javascript;charset=utf-8,
|
|
6
|
+
const React = window.React;
|
|
7
|
+
export default React;
|
|
8
|
+
export const {
|
|
9
|
+
Component, PureComponent, createContext, useContext, useState, useEffect,
|
|
10
|
+
useCallback, useMemo, useRef, forwardRef, createElement, Fragment, memo, lazy, Suspense,
|
|
11
|
+
useLayoutEffect, useId
|
|
12
|
+
} = React;`, o = () => `data:text/javascript;charset=utf-8,
|
|
13
|
+
const React = window.React;
|
|
14
|
+
export const Fragment = React.Fragment;
|
|
15
|
+
export function jsx(type, props, key) {
|
|
16
|
+
const { children, ...restProps } = props || {};
|
|
17
|
+
return React.createElement(type, key !== undefined ? { ...restProps, key } : restProps, children);
|
|
18
|
+
}
|
|
19
|
+
export function jsxs(type, props, key) {
|
|
20
|
+
const { children, ...restProps } = props || {};
|
|
21
|
+
return React.createElement(type, key !== undefined ? { ...restProps, key } : restProps, ...(Array.isArray(children) ? children : [children]));
|
|
22
|
+
}`, p = (e = {}) => {
|
|
23
|
+
const r = { ...a, ...e }, t = o();
|
|
24
|
+
return {
|
|
25
|
+
imports: {
|
|
26
|
+
react: c(),
|
|
27
|
+
"react/jsx-runtime": t,
|
|
28
|
+
"react/jsx-dev-runtime": t,
|
|
29
|
+
// Some bundlers emit ".js" suffixed bare specifiers; map those too
|
|
30
|
+
"react/jsx-runtime.js": t,
|
|
31
|
+
"react/jsx-dev-runtime.js": t,
|
|
32
|
+
"react-dom": `https://esm.sh/react-dom@${r.reactDomVersion}`,
|
|
33
|
+
"react-dom/client": `https://esm.sh/react-dom@${r.reactDomVersion}/client`
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}, m = (e) => JSON.stringify(p(e));
|
|
37
|
+
export {
|
|
38
|
+
p as generateImportMap,
|
|
39
|
+
m as generateImportMapJson
|
|
40
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
async function n(e) {
|
|
2
|
+
try {
|
|
3
|
+
const o = await fetch(e, {
|
|
4
|
+
headers: {
|
|
5
|
+
"Content-Type": "application/json"
|
|
6
|
+
}
|
|
7
|
+
});
|
|
8
|
+
if (!o.ok)
|
|
9
|
+
throw new Error(
|
|
10
|
+
`Failed to fetch manifest: ${o.status} ${o.statusText}`
|
|
11
|
+
);
|
|
12
|
+
const t = await o.json();
|
|
13
|
+
if (!t || typeof t != "object" || !t.components || typeof t.components != "object")
|
|
14
|
+
throw new Error("Invalid manifest: missing 'components' object");
|
|
15
|
+
return t;
|
|
16
|
+
} catch (o) {
|
|
17
|
+
throw o instanceof Error ? new Error(
|
|
18
|
+
`Manifest loading failed from ${e}: ${o.message}`
|
|
19
|
+
) : new Error(
|
|
20
|
+
`Manifest loading failed from ${e}: Unknown error`
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
n as fetchManifest
|
|
26
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
var u = Object.defineProperty;
|
|
2
|
+
var h = (a, e, t) => e in a ? u(a, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[e] = t;
|
|
3
|
+
var s = (a, e, t) => h(a, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import w from "react";
|
|
5
|
+
import M from "react-dom";
|
|
6
|
+
class f {
|
|
7
|
+
constructor() {
|
|
8
|
+
s(this, "loadedModules", /* @__PURE__ */ new Map());
|
|
9
|
+
s(this, "importMapInjected", !1);
|
|
10
|
+
}
|
|
11
|
+
prepareGlobalDependencies() {
|
|
12
|
+
window.React || (window.React = w), window.ReactDOM || (window.ReactDOM = M);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Ensure import map is injected before loading any modules
|
|
16
|
+
* Import maps MUST be added before any module scripts
|
|
17
|
+
*/
|
|
18
|
+
ensureImportMap() {
|
|
19
|
+
if (typeof window > "u" || this.importMapInjected) return;
|
|
20
|
+
if (document.querySelector(
|
|
21
|
+
'script[type="importmap"], script[type="importmap-shim"]'
|
|
22
|
+
)) {
|
|
23
|
+
this.importMapInjected = !0;
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
console.warn(
|
|
27
|
+
`Import map not found. Ensure an import map is included early in:
|
|
28
|
+
|
|
29
|
+
- pages router: the document head (e.g. in pages/_document.tsx).
|
|
30
|
+
|
|
31
|
+
- app router: the root layout head (e.g. in app/layout.tsx).`
|
|
32
|
+
), this.importMapInjected = !0;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Load remote React component from ES module URL
|
|
36
|
+
*
|
|
37
|
+
* @param options - Configuration object with bundleUrl and componentName
|
|
38
|
+
* @returns Promise that resolves to the loaded React component
|
|
39
|
+
* @throws Error if component loading fails or times out (10s)
|
|
40
|
+
*/
|
|
41
|
+
async loadComponent(e) {
|
|
42
|
+
const { bundleUrl: t, componentName: d } = e;
|
|
43
|
+
if (this.loadedModules.has(t)) {
|
|
44
|
+
const o = this.loadedModules.get(t), n = (o == null ? void 0 : o[d]) || (o == null ? void 0 : o.default);
|
|
45
|
+
if (n) return n;
|
|
46
|
+
}
|
|
47
|
+
this.prepareGlobalDependencies(), this.ensureImportMap();
|
|
48
|
+
try {
|
|
49
|
+
const o = await this.loadModuleViaScript(t), n = o[d] || o.default;
|
|
50
|
+
if (!n)
|
|
51
|
+
throw new Error(`Component ${d} not found in module`);
|
|
52
|
+
return this.loadedModules.set(t, o), n;
|
|
53
|
+
} catch (o) {
|
|
54
|
+
throw console.error("Failed to load component:", o), o;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Load ES module from external URL using dynamic script injection
|
|
59
|
+
* This bypasses Webpack's module resolution and works with import maps
|
|
60
|
+
*/
|
|
61
|
+
loadModuleViaScript(e) {
|
|
62
|
+
return new Promise((t, d) => {
|
|
63
|
+
const o = `__moduleCallback_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, n = 50, c = 200;
|
|
64
|
+
let l = 0;
|
|
65
|
+
const m = `
|
|
66
|
+
import * as loadedModule from '${e}';
|
|
67
|
+
window.${o} = loadedModule;
|
|
68
|
+
`, r = document.createElement("script");
|
|
69
|
+
r.type = "module-shim", r.textContent = m;
|
|
70
|
+
const i = setInterval(() => {
|
|
71
|
+
if (l++, window[o]) {
|
|
72
|
+
clearInterval(i);
|
|
73
|
+
const p = window[o];
|
|
74
|
+
delete window[o], r.parentNode && document.head.removeChild(r), t(p);
|
|
75
|
+
} else l >= c && (clearInterval(i), delete window[o], r.parentNode && document.head.removeChild(r), d(new Error(`Timeout loading module from ${e}`)));
|
|
76
|
+
}, n);
|
|
77
|
+
r.onerror = (p) => {
|
|
78
|
+
clearInterval(i), delete window[o], r.parentNode && document.head.removeChild(r), d(new Error(`Failed to load module from ${e}`));
|
|
79
|
+
}, document.head.appendChild(r);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Preload a module without extracting components
|
|
84
|
+
* Useful for warming up cache
|
|
85
|
+
*
|
|
86
|
+
* @param bundleUrl - URL of the module to preload
|
|
87
|
+
*/
|
|
88
|
+
async preloadModule(e) {
|
|
89
|
+
if (!this.loadedModules.has(e)) {
|
|
90
|
+
this.ensureImportMap();
|
|
91
|
+
try {
|
|
92
|
+
const t = await this.loadModuleViaScript(e);
|
|
93
|
+
this.loadedModules.set(e, t);
|
|
94
|
+
} catch (t) {
|
|
95
|
+
console.error(`Failed to preload module ${e}:`, t);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Check if a module has already been loaded
|
|
101
|
+
*
|
|
102
|
+
* @param bundleUrl - URL of the module to check
|
|
103
|
+
* @returns true if module is already loaded, false otherwise
|
|
104
|
+
*/
|
|
105
|
+
isLoaded(e) {
|
|
106
|
+
return this.loadedModules.has(e);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Clear all loaded modules from cache
|
|
110
|
+
* Useful for development/testing
|
|
111
|
+
*/
|
|
112
|
+
clearCache() {
|
|
113
|
+
this.loadedModules.clear();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const g = new f();
|
|
117
|
+
export {
|
|
118
|
+
f as ModuleLoader,
|
|
119
|
+
g as moduleLoader
|
|
120
|
+
};
|