@vxrn/vite-plugin-metro 1.2.17 → 1.2.18
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/dist/cjs/plugins/metroPlugin.cjs +45 -38
- package/dist/cjs/plugins/metroPlugin.js +83 -64
- package/dist/cjs/plugins/metroPlugin.js.map +1 -1
- package/dist/cjs/plugins/metroPlugin.native.js +53 -41
- package/dist/cjs/plugins/metroPlugin.native.js.map +1 -1
- package/dist/esm/plugins/metroPlugin.js +83 -64
- package/dist/esm/plugins/metroPlugin.js.map +1 -1
- package/dist/esm/plugins/metroPlugin.mjs +45 -38
- package/dist/esm/plugins/metroPlugin.mjs.map +1 -1
- package/dist/esm/plugins/metroPlugin.native.js +53 -41
- package/dist/esm/plugins/metroPlugin.native.js.map +1 -1
- package/package.json +3 -3
- package/src/plugins/metroPlugin.ts +130 -86
- package/types/plugins/metroPlugin.d.ts.map +1 -1
|
@@ -52,7 +52,9 @@ function metroPlugin(options = {}) {
|
|
|
52
52
|
logger,
|
|
53
53
|
root: projectRoot
|
|
54
54
|
} = server.config,
|
|
55
|
-
|
|
55
|
+
metroStartTime = Date.now();
|
|
56
|
+
let metroReady = !1;
|
|
57
|
+
const {
|
|
56
58
|
default: Metro
|
|
57
59
|
} = await (0, import_projectImport.projectImport)(projectRoot, "metro"),
|
|
58
60
|
{
|
|
@@ -64,29 +66,48 @@ function metroPlugin(options = {}) {
|
|
|
64
66
|
{
|
|
65
67
|
createDevMiddleware
|
|
66
68
|
} = await (0, import_projectImport.projectImport)(projectRoot, "@react-native/dev-middleware"),
|
|
67
|
-
config = await (0, import_getMetroConfigFromViteConfig.getMetroConfigFromViteConfig)(server.config, options)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
metroServer
|
|
72
|
-
} = await Metro.createConnectMiddleware(config, {
|
|
73
|
-
// Force enable file watching, even on CI.
|
|
74
|
-
// This is needed for HMR tests to work on CI.
|
|
75
|
-
watch: !0
|
|
76
|
-
});
|
|
77
|
-
(0, import_patchMetroServerWithViteConfigAndMetroPluginOptions.patchMetroServerWithViteConfigAndMetroPluginOptions)(metroServer, server.config, options);
|
|
78
|
-
const hmrServer = new MetroHmrServer(metroServer.getBundler(), metroServer.getCreateModuleId(), config),
|
|
79
|
-
reactNativeDevToolsUrl = `http://${typeof server.config.server.host == "boolean" ? "localhost" : server.config.server.host}:${server.config.server.port}`,
|
|
80
|
-
{
|
|
81
|
-
middleware: rnDevtoolsMiddleware,
|
|
82
|
-
websocketEndpoints: rnDevtoolsWebsocketEndpoints
|
|
83
|
-
} = createDevMiddleware({
|
|
84
|
-
projectRoot,
|
|
85
|
-
serverBaseUrl: reactNativeDevToolsUrl,
|
|
86
|
-
logger: console
|
|
87
|
-
});
|
|
88
|
-
server.middlewares.use(async (req, res, next) => {
|
|
69
|
+
config = await (0, import_getMetroConfigFromViteConfig.getMetroConfigFromViteConfig)(server.config, options);
|
|
70
|
+
let middleware, metroServer, hmrServer, websocketEndpoints, rnDevtoolsMiddleware;
|
|
71
|
+
const metroPromise = (async () => {
|
|
72
|
+
console.info("[metro] Starting Metro bundler in background...");
|
|
89
73
|
try {
|
|
74
|
+
const metroResult = await Metro.createConnectMiddleware(config, {
|
|
75
|
+
// Force enable file watching, even on CI.
|
|
76
|
+
// This is needed for HMR tests to work on CI.
|
|
77
|
+
watch: !0
|
|
78
|
+
});
|
|
79
|
+
middleware = metroResult.middleware, metroServer = metroResult.metroServer, (0, import_patchMetroServerWithViteConfigAndMetroPluginOptions.patchMetroServerWithViteConfigAndMetroPluginOptions)(metroServer, server.config, options), hmrServer = new MetroHmrServer(metroServer.getBundler(), metroServer.getCreateModuleId(), config);
|
|
80
|
+
const reactNativeDevToolsUrl = `http://${typeof server.config.server.host == "boolean" ? "localhost" : server.config.server.host}:${server.config.server.port}`,
|
|
81
|
+
devMiddleware = createDevMiddleware({
|
|
82
|
+
projectRoot,
|
|
83
|
+
serverBaseUrl: reactNativeDevToolsUrl,
|
|
84
|
+
logger: console
|
|
85
|
+
});
|
|
86
|
+
rnDevtoolsMiddleware = devMiddleware.middleware, websocketEndpoints = {
|
|
87
|
+
"/hot": createWebsocketServer({
|
|
88
|
+
websocketServer: hmrServer
|
|
89
|
+
}),
|
|
90
|
+
...devMiddleware.websocketEndpoints
|
|
91
|
+
}, metroReady = !0;
|
|
92
|
+
const metroElapsed = Date.now() - metroStartTime;
|
|
93
|
+
console.info(`[metro] Metro bundler ready (${metroElapsed}ms)`);
|
|
94
|
+
} catch (err) {
|
|
95
|
+
throw console.error("[metro] Error during Metro initialization:", err), err;
|
|
96
|
+
}
|
|
97
|
+
})();
|
|
98
|
+
metroPromise.catch(err => {
|
|
99
|
+
console.error("[metro] Failed to start Metro:", err);
|
|
100
|
+
}), metroPromise.then(() => {
|
|
101
|
+
server.httpServer?.on("upgrade", (request, socket, head) => {
|
|
102
|
+
const {
|
|
103
|
+
pathname
|
|
104
|
+
} = (0, import_node_url.parse)(request.url);
|
|
105
|
+
pathname != null && websocketEndpoints[pathname] && websocketEndpoints[pathname].handleUpgrade(request, socket, head, ws => {
|
|
106
|
+
websocketEndpoints[pathname].emit("connection", ws, request);
|
|
107
|
+
});
|
|
108
|
+
}), server.middlewares.use(rnDevtoolsMiddleware);
|
|
109
|
+
}), server.middlewares.use(async (req, res, next) => {
|
|
110
|
+
if (req.url?.includes(".bundle") && !metroReady && (await metroPromise), middleware) try {
|
|
90
111
|
if (req.url?.includes(".bundle")) {
|
|
91
112
|
const VITE_METRO_DEBUG_BUNDLE = process.env.VITE_METRO_DEBUG_BUNDLE;
|
|
92
113
|
if (VITE_METRO_DEBUG_BUNDLE && (0, import_node_fs.existsSync)(VITE_METRO_DEBUG_BUNDLE)) {
|
|
@@ -122,21 +143,7 @@ function metroPlugin(options = {}) {
|
|
|
122
143
|
await middleware(req, res, next);
|
|
123
144
|
} catch (error) {
|
|
124
145
|
console.error("Metro middleware error:", error), next();
|
|
125
|
-
}
|
|
126
|
-
}), server.middlewares.use(rnDevtoolsMiddleware);
|
|
127
|
-
const websocketEndpoints = {
|
|
128
|
-
"/hot": createWebsocketServer({
|
|
129
|
-
websocketServer: hmrServer
|
|
130
|
-
}),
|
|
131
|
-
...rnDevtoolsWebsocketEndpoints
|
|
132
|
-
};
|
|
133
|
-
server.httpServer?.on("upgrade", (request, socket, head) => {
|
|
134
|
-
const {
|
|
135
|
-
pathname
|
|
136
|
-
} = (0, import_node_url.parse)(request.url);
|
|
137
|
-
pathname != null && websocketEndpoints[pathname] && websocketEndpoints[pathname].handleUpgrade(request, socket, head, ws => {
|
|
138
|
-
websocketEndpoints[pathname].emit("connection", ws, request);
|
|
139
|
-
});
|
|
146
|
+
} else next();
|
|
140
147
|
});
|
|
141
148
|
}
|
|
142
149
|
};
|
|
@@ -33,74 +33,93 @@ function metroPlugin(options = {}) {
|
|
|
33
33
|
// projectRoot = config.root
|
|
34
34
|
// },
|
|
35
35
|
async configureServer(server) {
|
|
36
|
-
const { logger, root: projectRoot } = server.config,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const hmrServer = new MetroHmrServer(
|
|
43
|
-
metroServer.getBundler(),
|
|
44
|
-
metroServer.getCreateModuleId(),
|
|
45
|
-
config
|
|
46
|
-
), reactNativeDevToolsUrl = `http://${typeof server.config.server.host == "boolean" ? "localhost" : server.config.server.host}:${server.config.server.port}`, { middleware: rnDevtoolsMiddleware, websocketEndpoints: rnDevtoolsWebsocketEndpoints } = createDevMiddleware({
|
|
47
|
-
projectRoot,
|
|
48
|
-
serverBaseUrl: reactNativeDevToolsUrl,
|
|
49
|
-
logger: console
|
|
50
|
-
});
|
|
51
|
-
server.middlewares.use(async (req, res, next) => {
|
|
36
|
+
const { logger, root: projectRoot } = server.config, metroStartTime = Date.now();
|
|
37
|
+
let metroReady = !1;
|
|
38
|
+
const { default: Metro } = await (0, import_projectImport.projectImport)(projectRoot, "metro"), { default: MetroHmrServer } = await (0, import_projectImport.projectImport)(projectRoot, "metro/private/HmrServer"), { default: createWebsocketServer } = await (0, import_projectImport.projectImport)(projectRoot, "metro/private/lib/createWebsocketServer"), { createDevMiddleware } = await (0, import_projectImport.projectImport)(projectRoot, "@react-native/dev-middleware"), config = await (0, import_getMetroConfigFromViteConfig.getMetroConfigFromViteConfig)(server.config, options);
|
|
39
|
+
let middleware, metroServer, hmrServer, websocketEndpoints, rnDevtoolsMiddleware;
|
|
40
|
+
const metroPromise = (async () => {
|
|
41
|
+
console.info("[metro] Starting Metro bundler in background...");
|
|
52
42
|
try {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
43
|
+
const metroResult = await Metro.createConnectMiddleware(config, {
|
|
44
|
+
// Force enable file watching, even on CI.
|
|
45
|
+
// This is needed for HMR tests to work on CI.
|
|
46
|
+
watch: !0
|
|
47
|
+
});
|
|
48
|
+
middleware = metroResult.middleware, metroServer = metroResult.metroServer, (0, import_patchMetroServerWithViteConfigAndMetroPluginOptions.patchMetroServerWithViteConfigAndMetroPluginOptions)(metroServer, server.config, options), hmrServer = new MetroHmrServer(
|
|
49
|
+
metroServer.getBundler(),
|
|
50
|
+
metroServer.getCreateModuleId(),
|
|
51
|
+
config
|
|
52
|
+
);
|
|
53
|
+
const reactNativeDevToolsUrl = `http://${typeof server.config.server.host == "boolean" ? "localhost" : server.config.server.host}:${server.config.server.port}`, devMiddleware = createDevMiddleware({
|
|
54
|
+
projectRoot,
|
|
55
|
+
serverBaseUrl: reactNativeDevToolsUrl,
|
|
56
|
+
logger: console
|
|
57
|
+
});
|
|
58
|
+
rnDevtoolsMiddleware = devMiddleware.middleware, websocketEndpoints = {
|
|
59
|
+
"/hot": createWebsocketServer({
|
|
60
|
+
websocketServer: hmrServer
|
|
61
|
+
}),
|
|
62
|
+
...devMiddleware.websocketEndpoints
|
|
63
|
+
}, metroReady = !0;
|
|
64
|
+
const metroElapsed = Date.now() - metroStartTime;
|
|
65
|
+
console.info(`[metro] Metro bundler ready (${metroElapsed}ms)`);
|
|
66
|
+
} catch (err) {
|
|
67
|
+
throw console.error("[metro] Error during Metro initialization:", err), err;
|
|
68
|
+
}
|
|
69
|
+
})();
|
|
70
|
+
metroPromise.catch((err) => {
|
|
71
|
+
console.error("[metro] Failed to start Metro:", err);
|
|
72
|
+
}), metroPromise.then(() => {
|
|
73
|
+
server.httpServer?.on("upgrade", (request, socket, head) => {
|
|
74
|
+
const { pathname } = (0, import_node_url.parse)(request.url);
|
|
75
|
+
pathname != null && websocketEndpoints[pathname] && websocketEndpoints[pathname].handleUpgrade(request, socket, head, (ws) => {
|
|
76
|
+
websocketEndpoints[pathname].emit("connection", ws, request);
|
|
77
|
+
});
|
|
78
|
+
}), server.middlewares.use(rnDevtoolsMiddleware);
|
|
79
|
+
}), server.middlewares.use(async (req, res, next) => {
|
|
80
|
+
if (req.url?.includes(".bundle") && !metroReady && await metroPromise, middleware)
|
|
81
|
+
try {
|
|
82
|
+
if (req.url?.includes(".bundle")) {
|
|
83
|
+
const VITE_METRO_DEBUG_BUNDLE = process.env.VITE_METRO_DEBUG_BUNDLE;
|
|
84
|
+
if (VITE_METRO_DEBUG_BUNDLE && (0, import_node_fs.existsSync)(VITE_METRO_DEBUG_BUNDLE)) {
|
|
85
|
+
console.info(" !!! - serving debug bundle from", VITE_METRO_DEBUG_BUNDLE);
|
|
86
|
+
const content = await (0, import_promises.readFile)(VITE_METRO_DEBUG_BUNDLE, "utf-8");
|
|
87
|
+
res.setHeader("Content-Type", "application/javascript"), res.end(content);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (req.url === "/status" && // The path (`/status`) is too general and may conflict with the user's web app, so we also check the User-Agent header to ensure it's a request from a native app.
|
|
92
|
+
// Failing to handle this correctly will cause the native app to show a "Packager is not running at ..." error.
|
|
93
|
+
(req.headers["user-agent"]?.includes(
|
|
94
|
+
"CFNetwork/"
|
|
95
|
+
/* iOS */
|
|
96
|
+
) || req.headers["user-agent"]?.includes(
|
|
97
|
+
"okhttp/"
|
|
98
|
+
/* Android */
|
|
99
|
+
))) {
|
|
100
|
+
res.statusCode = 200, res.end("packager-status:running");
|
|
59
101
|
return;
|
|
60
102
|
}
|
|
103
|
+
if (req.url === "/open-stack-frame" && req.method === "POST") {
|
|
104
|
+
let body = "";
|
|
105
|
+
req.on("data", (chunk) => {
|
|
106
|
+
body += chunk.toString();
|
|
107
|
+
}), req.on("end", () => {
|
|
108
|
+
try {
|
|
109
|
+
const frame = JSON.parse(body);
|
|
110
|
+
(0, import_launch_editor.default)(frame.file), res.statusCode = 200, res.end("Stack frame opened in editor");
|
|
111
|
+
} catch (e) {
|
|
112
|
+
return console.error("Failed to parse stack frame:", e), res.statusCode = 400, res.end("Invalid stack frame JSON");
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
await middleware(req, res, next);
|
|
118
|
+
} catch (error) {
|
|
119
|
+
console.error("Metro middleware error:", error), next();
|
|
61
120
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
(req.headers["user-agent"]?.includes(
|
|
65
|
-
"CFNetwork/"
|
|
66
|
-
/* iOS */
|
|
67
|
-
) || req.headers["user-agent"]?.includes(
|
|
68
|
-
"okhttp/"
|
|
69
|
-
/* Android */
|
|
70
|
-
))) {
|
|
71
|
-
res.statusCode = 200, res.end("packager-status:running");
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
if (req.url === "/open-stack-frame" && req.method === "POST") {
|
|
75
|
-
let body = "";
|
|
76
|
-
req.on("data", (chunk) => {
|
|
77
|
-
body += chunk.toString();
|
|
78
|
-
}), req.on("end", () => {
|
|
79
|
-
try {
|
|
80
|
-
const frame = JSON.parse(body);
|
|
81
|
-
(0, import_launch_editor.default)(frame.file), res.statusCode = 200, res.end("Stack frame opened in editor");
|
|
82
|
-
} catch (e) {
|
|
83
|
-
return console.error("Failed to parse stack frame:", e), res.statusCode = 400, res.end("Invalid stack frame JSON");
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
await middleware(req, res, next);
|
|
89
|
-
} catch (error) {
|
|
90
|
-
console.error("Metro middleware error:", error), next();
|
|
91
|
-
}
|
|
92
|
-
}), server.middlewares.use(rnDevtoolsMiddleware);
|
|
93
|
-
const websocketEndpoints = {
|
|
94
|
-
"/hot": createWebsocketServer({
|
|
95
|
-
websocketServer: hmrServer
|
|
96
|
-
}),
|
|
97
|
-
...rnDevtoolsWebsocketEndpoints
|
|
98
|
-
};
|
|
99
|
-
server.httpServer?.on("upgrade", (request, socket, head) => {
|
|
100
|
-
const { pathname } = (0, import_node_url.parse)(request.url);
|
|
101
|
-
pathname != null && websocketEndpoints[pathname] && websocketEndpoints[pathname].handleUpgrade(request, socket, head, (ws) => {
|
|
102
|
-
websocketEndpoints[pathname].emit("connection", ws, request);
|
|
103
|
-
});
|
|
121
|
+
else
|
|
122
|
+
next();
|
|
104
123
|
});
|
|
105
124
|
}
|
|
106
125
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/plugins/metroPlugin.ts"],
|
|
4
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAA2B,oBAC3B,kBAAyB,6BACzB,kBAAsB,qBAEtB,uBAAyB,sCAWzB,uBAA8B,mCAE9B,sCAA6C,yDAC7C,6DAAoE;AAyC7D,SAAS,YAAY,UAA8B,CAAC,GAAiB;AAO1E,oBAAW,6BAAgC,SAEpC;AAAA,IACL,MAAM;AAAA;AAAA;AAAA;AAAA,IAKN,MAAM,gBAAgB,QAAQ;AAC5B,YAAM,EAAE,QAAQ,MAAM,YAAY,IAAI,OAAO,
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": ["launchEditor"]
|
|
6
6
|
}
|
|
@@ -51,11 +51,12 @@ function metroPlugin() {
|
|
|
51
51
|
// projectRoot = config.root
|
|
52
52
|
// },
|
|
53
53
|
async configureServer(server) {
|
|
54
|
-
var
|
|
55
|
-
{
|
|
54
|
+
var {
|
|
56
55
|
logger,
|
|
57
56
|
root: projectRoot
|
|
58
57
|
} = server.config,
|
|
58
|
+
metroStartTime = Date.now(),
|
|
59
|
+
metroReady = !1,
|
|
59
60
|
{
|
|
60
61
|
default: Metro
|
|
61
62
|
} = await (0, import_projectImport.projectImport)(projectRoot, "metro"),
|
|
@@ -69,30 +70,55 @@ function metroPlugin() {
|
|
|
69
70
|
createDevMiddleware
|
|
70
71
|
} = await (0, import_projectImport.projectImport)(projectRoot, "@react-native/dev-middleware"),
|
|
71
72
|
config = await (0, import_getMetroConfigFromViteConfig.getMetroConfigFromViteConfig)(server.config, options),
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
73
|
+
middleware,
|
|
74
|
+
metroServer,
|
|
75
|
+
hmrServer,
|
|
76
|
+
websocketEndpoints,
|
|
77
|
+
rnDevtoolsMiddleware,
|
|
78
|
+
metroPromise = async function () {
|
|
79
|
+
console.info("[metro] Starting Metro bundler in background...");
|
|
80
|
+
try {
|
|
81
|
+
var metroResult = await Metro.createConnectMiddleware(config, {
|
|
82
|
+
// Force enable file watching, even on CI.
|
|
83
|
+
// This is needed for HMR tests to work on CI.
|
|
84
|
+
watch: !0
|
|
85
|
+
});
|
|
86
|
+
middleware = metroResult.middleware, metroServer = metroResult.metroServer, (0, import_patchMetroServerWithViteConfigAndMetroPluginOptions.patchMetroServerWithViteConfigAndMetroPluginOptions)(metroServer, server.config, options), hmrServer = new MetroHmrServer(metroServer.getBundler(), metroServer.getCreateModuleId(), config);
|
|
87
|
+
var reactNativeDevToolsUrl = `http://${typeof server.config.server.host == "boolean" ? "localhost" : server.config.server.host}:${server.config.server.port}`,
|
|
88
|
+
devMiddleware = createDevMiddleware({
|
|
89
|
+
projectRoot,
|
|
90
|
+
serverBaseUrl: reactNativeDevToolsUrl,
|
|
91
|
+
logger: console
|
|
92
|
+
});
|
|
93
|
+
rnDevtoolsMiddleware = devMiddleware.middleware, websocketEndpoints = {
|
|
94
|
+
"/hot": createWebsocketServer({
|
|
95
|
+
websocketServer: hmrServer
|
|
96
|
+
}),
|
|
97
|
+
...devMiddleware.websocketEndpoints
|
|
98
|
+
}, metroReady = !0;
|
|
99
|
+
var metroElapsed = Date.now() - metroStartTime;
|
|
100
|
+
console.info(`[metro] Metro bundler ready (${metroElapsed}ms)`);
|
|
101
|
+
} catch (err) {
|
|
102
|
+
throw console.error("[metro] Error during Metro initialization:", err), err;
|
|
103
|
+
}
|
|
104
|
+
}();
|
|
105
|
+
metroPromise.catch(function (err) {
|
|
106
|
+
console.error("[metro] Failed to start Metro:", err);
|
|
107
|
+
}), metroPromise.then(function () {
|
|
108
|
+
var _server_httpServer;
|
|
109
|
+
(_server_httpServer = server.httpServer) === null || _server_httpServer === void 0 || _server_httpServer.on("upgrade", function (request, socket, head) {
|
|
110
|
+
var {
|
|
111
|
+
pathname
|
|
112
|
+
} = (0, import_url.parse)(request.url);
|
|
113
|
+
pathname != null && websocketEndpoints[pathname] && websocketEndpoints[pathname].handleUpgrade(request, socket, head, function (ws) {
|
|
114
|
+
websocketEndpoints[pathname].emit("connection", ws, request);
|
|
115
|
+
});
|
|
116
|
+
}), server.middlewares.use(rnDevtoolsMiddleware);
|
|
117
|
+
}), server.middlewares.use(async function (req, res, next) {
|
|
118
|
+
var _req_url;
|
|
119
|
+
if (!((_req_url = req.url) === null || _req_url === void 0) && _req_url.includes(".bundle") && !metroReady && (await metroPromise), middleware) try {
|
|
120
|
+
var _req_url1, _req_headers_useragent, _req_headers_useragent1;
|
|
121
|
+
if (!((_req_url1 = req.url) === null || _req_url1 === void 0) && _req_url1.includes(".bundle")) {
|
|
96
122
|
var VITE_METRO_DEBUG_BUNDLE = process.env.VITE_METRO_DEBUG_BUNDLE;
|
|
97
123
|
if (VITE_METRO_DEBUG_BUNDLE && (0, import_fs.existsSync)(VITE_METRO_DEBUG_BUNDLE)) {
|
|
98
124
|
console.info(" !!! - serving debug bundle from", VITE_METRO_DEBUG_BUNDLE);
|
|
@@ -122,21 +148,7 @@ function metroPlugin() {
|
|
|
122
148
|
await middleware(req, res, next);
|
|
123
149
|
} catch (error) {
|
|
124
150
|
console.error("Metro middleware error:", error), next();
|
|
125
|
-
}
|
|
126
|
-
}), server.middlewares.use(rnDevtoolsMiddleware);
|
|
127
|
-
var websocketEndpoints = {
|
|
128
|
-
"/hot": createWebsocketServer({
|
|
129
|
-
websocketServer: hmrServer
|
|
130
|
-
}),
|
|
131
|
-
...rnDevtoolsWebsocketEndpoints
|
|
132
|
-
};
|
|
133
|
-
(_server_httpServer = server.httpServer) === null || _server_httpServer === void 0 || _server_httpServer.on("upgrade", function (request, socket, head) {
|
|
134
|
-
var {
|
|
135
|
-
pathname
|
|
136
|
-
} = (0, import_url.parse)(request.url);
|
|
137
|
-
pathname != null && websocketEndpoints[pathname] && websocketEndpoints[pathname].handleUpgrade(request, socket, head, function (ws) {
|
|
138
|
-
websocketEndpoints[pathname].emit("connection", ws, request);
|
|
139
|
-
});
|
|
151
|
+
} else next();
|
|
140
152
|
});
|
|
141
153
|
}
|
|
142
154
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["__toCommonJS","mod","__copyProps","__defProp","value","metroPlugin_exports","__export","metroPlugin","module","exports","import_fs","require","import_promises","import_url","import_launch_editor","__toESM","import_projectImport","import_getMetroConfigFromViteConfig","import_patchMetroServerWithViteConfigAndMetroPluginOptions","options","arguments","length","globalThis","__viteMetroPluginOptions__","name","configureServer","server","
|
|
1
|
+
{"version":3,"names":["__toCommonJS","mod","__copyProps","__defProp","value","metroPlugin_exports","__export","metroPlugin","module","exports","import_fs","require","import_promises","import_url","import_launch_editor","__toESM","import_projectImport","import_getMetroConfigFromViteConfig","import_patchMetroServerWithViteConfigAndMetroPluginOptions","options","arguments","length","globalThis","__viteMetroPluginOptions__","name","configureServer","server","logger","root","projectRoot","config","metroStartTime","Date","now","metroReady","default","Metro","projectImport","MetroHmrServer","createWebsocketServer","createDevMiddleware","getMetroConfigFromViteConfig","middleware","metroServer","hmrServer","websocketEndpoints","rnDevtoolsMiddleware","metroPromise","console","info","metroResult","createConnectMiddleware","watch","patchMetroServerWithViteConfigAndMetroPluginOptions","getBundler","getCreateModuleId","reactNativeDevToolsUrl","host","port","devMiddleware","serverBaseUrl","websocketServer","metroElapsed","err","error","catch","then","_server_httpServer","httpServer","on","request","socket","head","pathname","parse","url","handleUpgrade","ws","emit","middlewares","use","req","res","next","_req_url","includes","_req_url1","_req_headers_useragent","_req_headers_useragent1","VITE_METRO_DEBUG_BUNDLE","process","env","existsSync","content","readFile","setHeader","end","headers","statusCode","method","body","chunk","toString","frame","JSON","file","e"],"sources":["../../../src/plugins/metroPlugin.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -12,74 +12,93 @@ function metroPlugin(options = {}) {
|
|
|
12
12
|
// projectRoot = config.root
|
|
13
13
|
// },
|
|
14
14
|
async configureServer(server) {
|
|
15
|
-
const { logger, root: projectRoot } = server.config,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const hmrServer = new MetroHmrServer(
|
|
22
|
-
metroServer.getBundler(),
|
|
23
|
-
metroServer.getCreateModuleId(),
|
|
24
|
-
config
|
|
25
|
-
), reactNativeDevToolsUrl = `http://${typeof server.config.server.host == "boolean" ? "localhost" : server.config.server.host}:${server.config.server.port}`, { middleware: rnDevtoolsMiddleware, websocketEndpoints: rnDevtoolsWebsocketEndpoints } = createDevMiddleware({
|
|
26
|
-
projectRoot,
|
|
27
|
-
serverBaseUrl: reactNativeDevToolsUrl,
|
|
28
|
-
logger: console
|
|
29
|
-
});
|
|
30
|
-
server.middlewares.use(async (req, res, next) => {
|
|
15
|
+
const { logger, root: projectRoot } = server.config, metroStartTime = Date.now();
|
|
16
|
+
let metroReady = !1;
|
|
17
|
+
const { default: Metro } = await projectImport(projectRoot, "metro"), { default: MetroHmrServer } = await projectImport(projectRoot, "metro/private/HmrServer"), { default: createWebsocketServer } = await projectImport(projectRoot, "metro/private/lib/createWebsocketServer"), { createDevMiddleware } = await projectImport(projectRoot, "@react-native/dev-middleware"), config = await getMetroConfigFromViteConfig(server.config, options);
|
|
18
|
+
let middleware, metroServer, hmrServer, websocketEndpoints, rnDevtoolsMiddleware;
|
|
19
|
+
const metroPromise = (async () => {
|
|
20
|
+
console.info("[metro] Starting Metro bundler in background...");
|
|
31
21
|
try {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
22
|
+
const metroResult = await Metro.createConnectMiddleware(config, {
|
|
23
|
+
// Force enable file watching, even on CI.
|
|
24
|
+
// This is needed for HMR tests to work on CI.
|
|
25
|
+
watch: !0
|
|
26
|
+
});
|
|
27
|
+
middleware = metroResult.middleware, metroServer = metroResult.metroServer, patchMetroServerWithViteConfigAndMetroPluginOptions(metroServer, server.config, options), hmrServer = new MetroHmrServer(
|
|
28
|
+
metroServer.getBundler(),
|
|
29
|
+
metroServer.getCreateModuleId(),
|
|
30
|
+
config
|
|
31
|
+
);
|
|
32
|
+
const reactNativeDevToolsUrl = `http://${typeof server.config.server.host == "boolean" ? "localhost" : server.config.server.host}:${server.config.server.port}`, devMiddleware = createDevMiddleware({
|
|
33
|
+
projectRoot,
|
|
34
|
+
serverBaseUrl: reactNativeDevToolsUrl,
|
|
35
|
+
logger: console
|
|
36
|
+
});
|
|
37
|
+
rnDevtoolsMiddleware = devMiddleware.middleware, websocketEndpoints = {
|
|
38
|
+
"/hot": createWebsocketServer({
|
|
39
|
+
websocketServer: hmrServer
|
|
40
|
+
}),
|
|
41
|
+
...devMiddleware.websocketEndpoints
|
|
42
|
+
}, metroReady = !0;
|
|
43
|
+
const metroElapsed = Date.now() - metroStartTime;
|
|
44
|
+
console.info(`[metro] Metro bundler ready (${metroElapsed}ms)`);
|
|
45
|
+
} catch (err) {
|
|
46
|
+
throw console.error("[metro] Error during Metro initialization:", err), err;
|
|
47
|
+
}
|
|
48
|
+
})();
|
|
49
|
+
metroPromise.catch((err) => {
|
|
50
|
+
console.error("[metro] Failed to start Metro:", err);
|
|
51
|
+
}), metroPromise.then(() => {
|
|
52
|
+
server.httpServer?.on("upgrade", (request, socket, head) => {
|
|
53
|
+
const { pathname } = parse(request.url);
|
|
54
|
+
pathname != null && websocketEndpoints[pathname] && websocketEndpoints[pathname].handleUpgrade(request, socket, head, (ws) => {
|
|
55
|
+
websocketEndpoints[pathname].emit("connection", ws, request);
|
|
56
|
+
});
|
|
57
|
+
}), server.middlewares.use(rnDevtoolsMiddleware);
|
|
58
|
+
}), server.middlewares.use(async (req, res, next) => {
|
|
59
|
+
if (req.url?.includes(".bundle") && !metroReady && await metroPromise, middleware)
|
|
60
|
+
try {
|
|
61
|
+
if (req.url?.includes(".bundle")) {
|
|
62
|
+
const VITE_METRO_DEBUG_BUNDLE = process.env.VITE_METRO_DEBUG_BUNDLE;
|
|
63
|
+
if (VITE_METRO_DEBUG_BUNDLE && existsSync(VITE_METRO_DEBUG_BUNDLE)) {
|
|
64
|
+
console.info(" !!! - serving debug bundle from", VITE_METRO_DEBUG_BUNDLE);
|
|
65
|
+
const content = await readFile(VITE_METRO_DEBUG_BUNDLE, "utf-8");
|
|
66
|
+
res.setHeader("Content-Type", "application/javascript"), res.end(content);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (req.url === "/status" && // The path (`/status`) is too general and may conflict with the user's web app, so we also check the User-Agent header to ensure it's a request from a native app.
|
|
71
|
+
// Failing to handle this correctly will cause the native app to show a "Packager is not running at ..." error.
|
|
72
|
+
(req.headers["user-agent"]?.includes(
|
|
73
|
+
"CFNetwork/"
|
|
74
|
+
/* iOS */
|
|
75
|
+
) || req.headers["user-agent"]?.includes(
|
|
76
|
+
"okhttp/"
|
|
77
|
+
/* Android */
|
|
78
|
+
))) {
|
|
79
|
+
res.statusCode = 200, res.end("packager-status:running");
|
|
38
80
|
return;
|
|
39
81
|
}
|
|
82
|
+
if (req.url === "/open-stack-frame" && req.method === "POST") {
|
|
83
|
+
let body = "";
|
|
84
|
+
req.on("data", (chunk) => {
|
|
85
|
+
body += chunk.toString();
|
|
86
|
+
}), req.on("end", () => {
|
|
87
|
+
try {
|
|
88
|
+
const frame = JSON.parse(body);
|
|
89
|
+
launchEditor(frame.file), res.statusCode = 200, res.end("Stack frame opened in editor");
|
|
90
|
+
} catch (e) {
|
|
91
|
+
return console.error("Failed to parse stack frame:", e), res.statusCode = 400, res.end("Invalid stack frame JSON");
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
await middleware(req, res, next);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
console.error("Metro middleware error:", error), next();
|
|
40
99
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
(req.headers["user-agent"]?.includes(
|
|
44
|
-
"CFNetwork/"
|
|
45
|
-
/* iOS */
|
|
46
|
-
) || req.headers["user-agent"]?.includes(
|
|
47
|
-
"okhttp/"
|
|
48
|
-
/* Android */
|
|
49
|
-
))) {
|
|
50
|
-
res.statusCode = 200, res.end("packager-status:running");
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
if (req.url === "/open-stack-frame" && req.method === "POST") {
|
|
54
|
-
let body = "";
|
|
55
|
-
req.on("data", (chunk) => {
|
|
56
|
-
body += chunk.toString();
|
|
57
|
-
}), req.on("end", () => {
|
|
58
|
-
try {
|
|
59
|
-
const frame = JSON.parse(body);
|
|
60
|
-
launchEditor(frame.file), res.statusCode = 200, res.end("Stack frame opened in editor");
|
|
61
|
-
} catch (e) {
|
|
62
|
-
return console.error("Failed to parse stack frame:", e), res.statusCode = 400, res.end("Invalid stack frame JSON");
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
await middleware(req, res, next);
|
|
68
|
-
} catch (error) {
|
|
69
|
-
console.error("Metro middleware error:", error), next();
|
|
70
|
-
}
|
|
71
|
-
}), server.middlewares.use(rnDevtoolsMiddleware);
|
|
72
|
-
const websocketEndpoints = {
|
|
73
|
-
"/hot": createWebsocketServer({
|
|
74
|
-
websocketServer: hmrServer
|
|
75
|
-
}),
|
|
76
|
-
...rnDevtoolsWebsocketEndpoints
|
|
77
|
-
};
|
|
78
|
-
server.httpServer?.on("upgrade", (request, socket, head) => {
|
|
79
|
-
const { pathname } = parse(request.url);
|
|
80
|
-
pathname != null && websocketEndpoints[pathname] && websocketEndpoints[pathname].handleUpgrade(request, socket, head, (ws) => {
|
|
81
|
-
websocketEndpoints[pathname].emit("connection", ws, request);
|
|
82
|
-
});
|
|
100
|
+
else
|
|
101
|
+
next();
|
|
83
102
|
});
|
|
84
103
|
}
|
|
85
104
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/plugins/metroPlugin.ts"],
|
|
4
|
-
"mappings": "AAAA,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AACzB,SAAS,aAAa;AAEtB,OAAO,kBAAkB;AAWzB,SAAS,qBAAqB;AAE9B,SAAS,oCAAoC;AAC7C,SAAS,2DAA2D;AAyC7D,SAAS,YAAY,UAA8B,CAAC,GAAiB;AAO1E,oBAAW,6BAAgC,SAEpC;AAAA,IACL,MAAM;AAAA;AAAA;AAAA;AAAA,IAKN,MAAM,gBAAgB,QAAQ;AAC5B,YAAM,EAAE,QAAQ,MAAM,YAAY,IAAI,OAAO,
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -16,7 +16,9 @@ function metroPlugin(options = {}) {
|
|
|
16
16
|
logger,
|
|
17
17
|
root: projectRoot
|
|
18
18
|
} = server.config,
|
|
19
|
-
|
|
19
|
+
metroStartTime = Date.now();
|
|
20
|
+
let metroReady = !1;
|
|
21
|
+
const {
|
|
20
22
|
default: Metro
|
|
21
23
|
} = await projectImport(projectRoot, "metro"),
|
|
22
24
|
{
|
|
@@ -28,29 +30,48 @@ function metroPlugin(options = {}) {
|
|
|
28
30
|
{
|
|
29
31
|
createDevMiddleware
|
|
30
32
|
} = await projectImport(projectRoot, "@react-native/dev-middleware"),
|
|
31
|
-
config = await getMetroConfigFromViteConfig(server.config, options)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
metroServer
|
|
36
|
-
} = await Metro.createConnectMiddleware(config, {
|
|
37
|
-
// Force enable file watching, even on CI.
|
|
38
|
-
// This is needed for HMR tests to work on CI.
|
|
39
|
-
watch: !0
|
|
40
|
-
});
|
|
41
|
-
patchMetroServerWithViteConfigAndMetroPluginOptions(metroServer, server.config, options);
|
|
42
|
-
const hmrServer = new MetroHmrServer(metroServer.getBundler(), metroServer.getCreateModuleId(), config),
|
|
43
|
-
reactNativeDevToolsUrl = `http://${typeof server.config.server.host == "boolean" ? "localhost" : server.config.server.host}:${server.config.server.port}`,
|
|
44
|
-
{
|
|
45
|
-
middleware: rnDevtoolsMiddleware,
|
|
46
|
-
websocketEndpoints: rnDevtoolsWebsocketEndpoints
|
|
47
|
-
} = createDevMiddleware({
|
|
48
|
-
projectRoot,
|
|
49
|
-
serverBaseUrl: reactNativeDevToolsUrl,
|
|
50
|
-
logger: console
|
|
51
|
-
});
|
|
52
|
-
server.middlewares.use(async (req, res, next) => {
|
|
33
|
+
config = await getMetroConfigFromViteConfig(server.config, options);
|
|
34
|
+
let middleware, metroServer, hmrServer, websocketEndpoints, rnDevtoolsMiddleware;
|
|
35
|
+
const metroPromise = (async () => {
|
|
36
|
+
console.info("[metro] Starting Metro bundler in background...");
|
|
53
37
|
try {
|
|
38
|
+
const metroResult = await Metro.createConnectMiddleware(config, {
|
|
39
|
+
// Force enable file watching, even on CI.
|
|
40
|
+
// This is needed for HMR tests to work on CI.
|
|
41
|
+
watch: !0
|
|
42
|
+
});
|
|
43
|
+
middleware = metroResult.middleware, metroServer = metroResult.metroServer, patchMetroServerWithViteConfigAndMetroPluginOptions(metroServer, server.config, options), hmrServer = new MetroHmrServer(metroServer.getBundler(), metroServer.getCreateModuleId(), config);
|
|
44
|
+
const reactNativeDevToolsUrl = `http://${typeof server.config.server.host == "boolean" ? "localhost" : server.config.server.host}:${server.config.server.port}`,
|
|
45
|
+
devMiddleware = createDevMiddleware({
|
|
46
|
+
projectRoot,
|
|
47
|
+
serverBaseUrl: reactNativeDevToolsUrl,
|
|
48
|
+
logger: console
|
|
49
|
+
});
|
|
50
|
+
rnDevtoolsMiddleware = devMiddleware.middleware, websocketEndpoints = {
|
|
51
|
+
"/hot": createWebsocketServer({
|
|
52
|
+
websocketServer: hmrServer
|
|
53
|
+
}),
|
|
54
|
+
...devMiddleware.websocketEndpoints
|
|
55
|
+
}, metroReady = !0;
|
|
56
|
+
const metroElapsed = Date.now() - metroStartTime;
|
|
57
|
+
console.info(`[metro] Metro bundler ready (${metroElapsed}ms)`);
|
|
58
|
+
} catch (err) {
|
|
59
|
+
throw console.error("[metro] Error during Metro initialization:", err), err;
|
|
60
|
+
}
|
|
61
|
+
})();
|
|
62
|
+
metroPromise.catch(err => {
|
|
63
|
+
console.error("[metro] Failed to start Metro:", err);
|
|
64
|
+
}), metroPromise.then(() => {
|
|
65
|
+
server.httpServer?.on("upgrade", (request, socket, head) => {
|
|
66
|
+
const {
|
|
67
|
+
pathname
|
|
68
|
+
} = parse(request.url);
|
|
69
|
+
pathname != null && websocketEndpoints[pathname] && websocketEndpoints[pathname].handleUpgrade(request, socket, head, ws => {
|
|
70
|
+
websocketEndpoints[pathname].emit("connection", ws, request);
|
|
71
|
+
});
|
|
72
|
+
}), server.middlewares.use(rnDevtoolsMiddleware);
|
|
73
|
+
}), server.middlewares.use(async (req, res, next) => {
|
|
74
|
+
if (req.url?.includes(".bundle") && !metroReady && (await metroPromise), middleware) try {
|
|
54
75
|
if (req.url?.includes(".bundle")) {
|
|
55
76
|
const VITE_METRO_DEBUG_BUNDLE = process.env.VITE_METRO_DEBUG_BUNDLE;
|
|
56
77
|
if (VITE_METRO_DEBUG_BUNDLE && existsSync(VITE_METRO_DEBUG_BUNDLE)) {
|
|
@@ -86,21 +107,7 @@ function metroPlugin(options = {}) {
|
|
|
86
107
|
await middleware(req, res, next);
|
|
87
108
|
} catch (error) {
|
|
88
109
|
console.error("Metro middleware error:", error), next();
|
|
89
|
-
}
|
|
90
|
-
}), server.middlewares.use(rnDevtoolsMiddleware);
|
|
91
|
-
const websocketEndpoints = {
|
|
92
|
-
"/hot": createWebsocketServer({
|
|
93
|
-
websocketServer: hmrServer
|
|
94
|
-
}),
|
|
95
|
-
...rnDevtoolsWebsocketEndpoints
|
|
96
|
-
};
|
|
97
|
-
server.httpServer?.on("upgrade", (request, socket, head) => {
|
|
98
|
-
const {
|
|
99
|
-
pathname
|
|
100
|
-
} = parse(request.url);
|
|
101
|
-
pathname != null && websocketEndpoints[pathname] && websocketEndpoints[pathname].handleUpgrade(request, socket, head, ws => {
|
|
102
|
-
websocketEndpoints[pathname].emit("connection", ws, request);
|
|
103
|
-
});
|
|
110
|
+
} else next();
|
|
104
111
|
});
|
|
105
112
|
}
|
|
106
113
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["existsSync","readFile","parse","launchEditor","projectImport","getMetroConfigFromViteConfig","patchMetroServerWithViteConfigAndMetroPluginOptions","metroPlugin","options","globalThis","__viteMetroPluginOptions__","name","configureServer","server","logger","root","projectRoot","config","default","Metro","MetroHmrServer","createWebsocketServer","createDevMiddleware","middleware","
|
|
1
|
+
{"version":3,"names":["existsSync","readFile","parse","launchEditor","projectImport","getMetroConfigFromViteConfig","patchMetroServerWithViteConfigAndMetroPluginOptions","metroPlugin","options","globalThis","__viteMetroPluginOptions__","name","configureServer","server","logger","root","projectRoot","config","metroStartTime","Date","now","metroReady","default","Metro","MetroHmrServer","createWebsocketServer","createDevMiddleware","middleware","metroServer","hmrServer","websocketEndpoints","rnDevtoolsMiddleware","metroPromise","console","info","metroResult","createConnectMiddleware","watch","getBundler","getCreateModuleId","reactNativeDevToolsUrl","host","port","devMiddleware","serverBaseUrl","websocketServer","metroElapsed","err","error","catch","then","httpServer","on","request","socket","head","pathname","url","handleUpgrade","ws","emit","middlewares","use","req","res","next","includes","VITE_METRO_DEBUG_BUNDLE","process","env","content","setHeader","end","headers","statusCode","method","body","chunk","toString","frame","JSON","file","e"],"sources":["../../../src/plugins/metroPlugin.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -13,11 +13,12 @@ function metroPlugin() {
|
|
|
13
13
|
// projectRoot = config.root
|
|
14
14
|
// },
|
|
15
15
|
async configureServer(server) {
|
|
16
|
-
var
|
|
17
|
-
{
|
|
16
|
+
var {
|
|
18
17
|
logger,
|
|
19
18
|
root: projectRoot
|
|
20
19
|
} = server.config,
|
|
20
|
+
metroStartTime = Date.now(),
|
|
21
|
+
metroReady = !1,
|
|
21
22
|
{
|
|
22
23
|
default: Metro
|
|
23
24
|
} = await projectImport(projectRoot, "metro"),
|
|
@@ -31,30 +32,55 @@ function metroPlugin() {
|
|
|
31
32
|
createDevMiddleware
|
|
32
33
|
} = await projectImport(projectRoot, "@react-native/dev-middleware"),
|
|
33
34
|
config = await getMetroConfigFromViteConfig(server.config, options),
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
35
|
+
middleware,
|
|
36
|
+
metroServer,
|
|
37
|
+
hmrServer,
|
|
38
|
+
websocketEndpoints,
|
|
39
|
+
rnDevtoolsMiddleware,
|
|
40
|
+
metroPromise = async function () {
|
|
41
|
+
console.info("[metro] Starting Metro bundler in background...");
|
|
42
|
+
try {
|
|
43
|
+
var metroResult = await Metro.createConnectMiddleware(config, {
|
|
44
|
+
// Force enable file watching, even on CI.
|
|
45
|
+
// This is needed for HMR tests to work on CI.
|
|
46
|
+
watch: !0
|
|
47
|
+
});
|
|
48
|
+
middleware = metroResult.middleware, metroServer = metroResult.metroServer, patchMetroServerWithViteConfigAndMetroPluginOptions(metroServer, server.config, options), hmrServer = new MetroHmrServer(metroServer.getBundler(), metroServer.getCreateModuleId(), config);
|
|
49
|
+
var reactNativeDevToolsUrl = `http://${typeof server.config.server.host == "boolean" ? "localhost" : server.config.server.host}:${server.config.server.port}`,
|
|
50
|
+
devMiddleware = createDevMiddleware({
|
|
51
|
+
projectRoot,
|
|
52
|
+
serverBaseUrl: reactNativeDevToolsUrl,
|
|
53
|
+
logger: console
|
|
54
|
+
});
|
|
55
|
+
rnDevtoolsMiddleware = devMiddleware.middleware, websocketEndpoints = {
|
|
56
|
+
"/hot": createWebsocketServer({
|
|
57
|
+
websocketServer: hmrServer
|
|
58
|
+
}),
|
|
59
|
+
...devMiddleware.websocketEndpoints
|
|
60
|
+
}, metroReady = !0;
|
|
61
|
+
var metroElapsed = Date.now() - metroStartTime;
|
|
62
|
+
console.info(`[metro] Metro bundler ready (${metroElapsed}ms)`);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
throw console.error("[metro] Error during Metro initialization:", err), err;
|
|
65
|
+
}
|
|
66
|
+
}();
|
|
67
|
+
metroPromise.catch(function (err) {
|
|
68
|
+
console.error("[metro] Failed to start Metro:", err);
|
|
69
|
+
}), metroPromise.then(function () {
|
|
70
|
+
var _server_httpServer;
|
|
71
|
+
(_server_httpServer = server.httpServer) === null || _server_httpServer === void 0 || _server_httpServer.on("upgrade", function (request, socket, head) {
|
|
72
|
+
var {
|
|
73
|
+
pathname
|
|
74
|
+
} = parse(request.url);
|
|
75
|
+
pathname != null && websocketEndpoints[pathname] && websocketEndpoints[pathname].handleUpgrade(request, socket, head, function (ws) {
|
|
76
|
+
websocketEndpoints[pathname].emit("connection", ws, request);
|
|
77
|
+
});
|
|
78
|
+
}), server.middlewares.use(rnDevtoolsMiddleware);
|
|
79
|
+
}), server.middlewares.use(async function (req, res, next) {
|
|
80
|
+
var _req_url;
|
|
81
|
+
if (!((_req_url = req.url) === null || _req_url === void 0) && _req_url.includes(".bundle") && !metroReady && (await metroPromise), middleware) try {
|
|
82
|
+
var _req_url1, _req_headers_useragent, _req_headers_useragent1;
|
|
83
|
+
if (!((_req_url1 = req.url) === null || _req_url1 === void 0) && _req_url1.includes(".bundle")) {
|
|
58
84
|
var VITE_METRO_DEBUG_BUNDLE = process.env.VITE_METRO_DEBUG_BUNDLE;
|
|
59
85
|
if (VITE_METRO_DEBUG_BUNDLE && existsSync(VITE_METRO_DEBUG_BUNDLE)) {
|
|
60
86
|
console.info(" !!! - serving debug bundle from", VITE_METRO_DEBUG_BUNDLE);
|
|
@@ -84,21 +110,7 @@ function metroPlugin() {
|
|
|
84
110
|
await middleware(req, res, next);
|
|
85
111
|
} catch (error) {
|
|
86
112
|
console.error("Metro middleware error:", error), next();
|
|
87
|
-
}
|
|
88
|
-
}), server.middlewares.use(rnDevtoolsMiddleware);
|
|
89
|
-
var websocketEndpoints = {
|
|
90
|
-
"/hot": createWebsocketServer({
|
|
91
|
-
websocketServer: hmrServer
|
|
92
|
-
}),
|
|
93
|
-
...rnDevtoolsWebsocketEndpoints
|
|
94
|
-
};
|
|
95
|
-
(_server_httpServer = server.httpServer) === null || _server_httpServer === void 0 || _server_httpServer.on("upgrade", function (request, socket, head) {
|
|
96
|
-
var {
|
|
97
|
-
pathname
|
|
98
|
-
} = parse(request.url);
|
|
99
|
-
pathname != null && websocketEndpoints[pathname] && websocketEndpoints[pathname].handleUpgrade(request, socket, head, function (ws) {
|
|
100
|
-
websocketEndpoints[pathname].emit("connection", ws, request);
|
|
101
|
-
});
|
|
113
|
+
} else next();
|
|
102
114
|
});
|
|
103
115
|
}
|
|
104
116
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["existsSync","readFile","parse","launchEditor","projectImport","getMetroConfigFromViteConfig","patchMetroServerWithViteConfigAndMetroPluginOptions","metroPlugin","options","arguments","length","globalThis","__viteMetroPluginOptions__","name","configureServer","server","
|
|
1
|
+
{"version":3,"names":["existsSync","readFile","parse","launchEditor","projectImport","getMetroConfigFromViteConfig","patchMetroServerWithViteConfigAndMetroPluginOptions","metroPlugin","options","arguments","length","globalThis","__viteMetroPluginOptions__","name","configureServer","server","logger","root","projectRoot","config","metroStartTime","Date","now","metroReady","default","Metro","MetroHmrServer","createWebsocketServer","createDevMiddleware","middleware","metroServer","hmrServer","websocketEndpoints","rnDevtoolsMiddleware","metroPromise","console","info","metroResult","createConnectMiddleware","watch","getBundler","getCreateModuleId","reactNativeDevToolsUrl","host","port","devMiddleware","serverBaseUrl","websocketServer","metroElapsed","err","error","catch","then","_server_httpServer","httpServer","on","request","socket","head","pathname","url","handleUpgrade","ws","emit","middlewares","use","req","res","next","_req_url","includes","_req_url1","_req_headers_useragent","_req_headers_useragent1","VITE_METRO_DEBUG_BUNDLE","process","env","content","setHeader","end","headers","statusCode","method","body","chunk","toString","frame","JSON","file","e"],"sources":["../../../src/plugins/metroPlugin.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vxrn/vite-plugin-metro",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.18",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/cjs",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"@babel/core": "^7.28.5",
|
|
61
61
|
"@babel/helper-plugin-utils": "^7.27.1",
|
|
62
62
|
"@babel/types": "^7.28.5",
|
|
63
|
-
"@vxrn/debug": "1.2.
|
|
63
|
+
"@vxrn/debug": "1.2.18",
|
|
64
64
|
"babel-preset-expo": "*",
|
|
65
65
|
"launch-editor": "^2.10.0",
|
|
66
66
|
"micromatch": "^4.0.8",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"@biomejs/biome": "2.3.3",
|
|
71
71
|
"@expo/metro-config": "^54.0.7",
|
|
72
72
|
"@react-native/dev-middleware": "^0.82.1",
|
|
73
|
-
"@tamagui/build": "^1.137.
|
|
73
|
+
"@tamagui/build": "^1.137.3",
|
|
74
74
|
"@types/babel__helper-plugin-utils": "^7",
|
|
75
75
|
"@types/node": "^24.10.0",
|
|
76
76
|
"depcheck": "^1.4.7",
|
|
@@ -75,6 +75,10 @@ export function metroPlugin(options: MetroPluginOptions = {}): PluginOption {
|
|
|
75
75
|
async configureServer(server) {
|
|
76
76
|
const { logger, root: projectRoot } = server.config
|
|
77
77
|
|
|
78
|
+
// Track Metro startup separately from Vite
|
|
79
|
+
const metroStartTime = Date.now()
|
|
80
|
+
let metroReady = false
|
|
81
|
+
|
|
78
82
|
const { default: Metro } = await projectImport<{
|
|
79
83
|
default: typeof MetroT
|
|
80
84
|
}>(projectRoot, 'metro')
|
|
@@ -90,113 +94,153 @@ export function metroPlugin(options: MetroPluginOptions = {}): PluginOption {
|
|
|
90
94
|
|
|
91
95
|
const config = await getMetroConfigFromViteConfig(server.config, options)
|
|
92
96
|
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
// Start Metro in background WITHOUT blocking Vite server startup
|
|
98
|
+
let middleware: Awaited<ReturnType<typeof MetroT.createConnectMiddleware>>['middleware']
|
|
99
|
+
let metroServer: Awaited<ReturnType<typeof MetroT.createConnectMiddleware>>['metroServer']
|
|
100
|
+
let hmrServer: MetroHmrServerT
|
|
101
|
+
let websocketEndpoints: Record<string, ReturnType<typeof createWebsocketServerT>>
|
|
102
|
+
let rnDevtoolsMiddleware: ReturnType<typeof createDevMiddlewareT>['middleware']
|
|
103
|
+
|
|
104
|
+
const metroPromise = (async () => {
|
|
105
|
+
console.info('[metro] Starting Metro bundler in background...')
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
// @ts-expect-error TODO
|
|
109
|
+
const metroResult = await Metro.createConnectMiddleware(config, {
|
|
110
|
+
// Force enable file watching, even on CI.
|
|
111
|
+
// This is needed for HMR tests to work on CI.
|
|
112
|
+
watch: true,
|
|
113
|
+
})
|
|
99
114
|
|
|
100
|
-
|
|
115
|
+
middleware = metroResult.middleware
|
|
116
|
+
metroServer = metroResult.metroServer
|
|
101
117
|
|
|
102
|
-
|
|
103
|
-
metroServer.getBundler(),
|
|
104
|
-
metroServer.getCreateModuleId(),
|
|
105
|
-
config
|
|
106
|
-
)
|
|
118
|
+
patchMetroServerWithViteConfigAndMetroPluginOptions(metroServer, server.config, options)
|
|
107
119
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
120
|
+
hmrServer = new MetroHmrServer(
|
|
121
|
+
metroServer.getBundler(),
|
|
122
|
+
metroServer.getCreateModuleId(),
|
|
123
|
+
config
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
const reactNativeDevToolsUrl = `http://${typeof server.config.server.host === 'boolean' ? 'localhost' : server.config.server.host}:${server.config.server.port}`
|
|
127
|
+
const devMiddleware = createDevMiddleware({
|
|
111
128
|
projectRoot,
|
|
112
129
|
serverBaseUrl: reactNativeDevToolsUrl,
|
|
113
130
|
logger: console,
|
|
114
131
|
})
|
|
115
132
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
console.info(` !!! - serving debug bundle from`, VITE_METRO_DEBUG_BUNDLE)
|
|
124
|
-
const content = await readFile(VITE_METRO_DEBUG_BUNDLE, 'utf-8')
|
|
125
|
-
res.setHeader('Content-Type', 'application/javascript')
|
|
126
|
-
res.end(content)
|
|
127
|
-
return
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
133
|
+
rnDevtoolsMiddleware = devMiddleware.middleware
|
|
134
|
+
websocketEndpoints = {
|
|
135
|
+
'/hot': createWebsocketServer({
|
|
136
|
+
websocketServer: hmrServer,
|
|
137
|
+
}),
|
|
138
|
+
...devMiddleware.websocketEndpoints,
|
|
139
|
+
}
|
|
131
140
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
req.headers['user-agent']?.includes('okhttp/' /* Android */))
|
|
141
|
-
) {
|
|
142
|
-
res.statusCode = 200
|
|
143
|
-
res.end('packager-status:running')
|
|
144
|
-
return
|
|
145
|
-
}
|
|
141
|
+
metroReady = true
|
|
142
|
+
const metroElapsed = Date.now() - metroStartTime
|
|
143
|
+
console.info(`[metro] Metro bundler ready (${metroElapsed}ms)`)
|
|
144
|
+
} catch (err) {
|
|
145
|
+
console.error('[metro] Error during Metro initialization:', err)
|
|
146
|
+
throw err
|
|
147
|
+
}
|
|
148
|
+
})()
|
|
146
149
|
|
|
147
|
-
|
|
148
|
-
|
|
150
|
+
// Don't await - let Metro initialize in parallel
|
|
151
|
+
metroPromise.catch((err) => {
|
|
152
|
+
console.error('[metro] Failed to start Metro:', err)
|
|
153
|
+
})
|
|
149
154
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
155
|
+
// Setup websocket handling after Metro is ready
|
|
156
|
+
metroPromise.then(() => {
|
|
157
|
+
server.httpServer?.on('upgrade', (request, socket, head) => {
|
|
158
|
+
const { pathname } = parse(request.url!)
|
|
153
159
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
// https://github.com/yyx990803/launch-editor/blob/master/packages/launch-editor-middleware/index.js
|
|
159
|
-
launchEditor(frame.file)
|
|
160
|
-
res.statusCode = 200
|
|
161
|
-
res.end('Stack frame opened in editor')
|
|
162
|
-
} catch (e) {
|
|
163
|
-
console.error('Failed to parse stack frame:', e)
|
|
164
|
-
res.statusCode = 400
|
|
165
|
-
return res.end('Invalid stack frame JSON')
|
|
166
|
-
}
|
|
160
|
+
if (pathname != null && websocketEndpoints[pathname]) {
|
|
161
|
+
websocketEndpoints[pathname].handleUpgrade(request, socket, head, (ws) => {
|
|
162
|
+
websocketEndpoints[pathname].emit('connection', ws, request)
|
|
167
163
|
})
|
|
168
|
-
|
|
169
|
-
return
|
|
170
164
|
}
|
|
165
|
+
})
|
|
171
166
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
} catch (error) {
|
|
175
|
-
// TODO: handle errors from Metro middleware?
|
|
176
|
-
console.error('Metro middleware error:', error)
|
|
177
|
-
next()
|
|
178
|
-
}
|
|
167
|
+
// Insert devtools middleware after Metro is ready
|
|
168
|
+
server.middlewares.use(rnDevtoolsMiddleware)
|
|
179
169
|
})
|
|
180
170
|
|
|
181
|
-
server.middlewares.use(
|
|
171
|
+
server.middlewares.use(async (req, res, next) => {
|
|
172
|
+
// Wait for Metro if it's a bundle request and Metro isn't ready yet
|
|
173
|
+
if (req.url?.includes('.bundle') && !metroReady) {
|
|
174
|
+
await metroPromise
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// If Metro middleware is ready, use it
|
|
178
|
+
if (middleware) {
|
|
179
|
+
try {
|
|
180
|
+
// Just for debugging purposes.
|
|
181
|
+
if (req.url?.includes('.bundle')) {
|
|
182
|
+
const VITE_METRO_DEBUG_BUNDLE = process.env.VITE_METRO_DEBUG_BUNDLE
|
|
183
|
+
if (VITE_METRO_DEBUG_BUNDLE) {
|
|
184
|
+
if (existsSync(VITE_METRO_DEBUG_BUNDLE)) {
|
|
185
|
+
console.info(` !!! - serving debug bundle from`, VITE_METRO_DEBUG_BUNDLE)
|
|
186
|
+
const content = await readFile(VITE_METRO_DEBUG_BUNDLE, 'utf-8')
|
|
187
|
+
res.setHeader('Content-Type', 'application/javascript')
|
|
188
|
+
res.end(content)
|
|
189
|
+
return
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
182
193
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
194
|
+
// Handle `isPackagerRunning` request from native app.
|
|
195
|
+
// Without this, people may see a `No script URL provided. Make sure the packager is running or you have embedded a JS bundle in your application bundle.`, `unsanitizedScriptURLString = (null)` error in their native app running with the "Debug" configuration.
|
|
196
|
+
// See: https://github.com/facebook/react-native/blob/v0.80.0-rc.4/packages/react-native/React/Base/RCTBundleURLProvider.mm#L87-L113
|
|
197
|
+
if (
|
|
198
|
+
req.url === '/status' &&
|
|
199
|
+
// The path (`/status`) is too general and may conflict with the user's web app, so we also check the User-Agent header to ensure it's a request from a native app.
|
|
200
|
+
// Failing to handle this correctly will cause the native app to show a "Packager is not running at ..." error.
|
|
201
|
+
(req.headers['user-agent']?.includes('CFNetwork/' /* iOS */) ||
|
|
202
|
+
req.headers['user-agent']?.includes('okhttp/' /* Android */))
|
|
203
|
+
) {
|
|
204
|
+
res.statusCode = 200
|
|
205
|
+
res.end('packager-status:running')
|
|
206
|
+
return
|
|
207
|
+
}
|
|
189
208
|
|
|
190
|
-
|
|
191
|
-
|
|
209
|
+
if (req.url === '/open-stack-frame' && req.method === 'POST') {
|
|
210
|
+
let body = ''
|
|
211
|
+
|
|
212
|
+
req.on('data', (chunk) => {
|
|
213
|
+
body += chunk.toString()
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
req.on('end', () => {
|
|
217
|
+
try {
|
|
218
|
+
const frame = JSON.parse(body)
|
|
219
|
+
|
|
220
|
+
// https://github.com/yyx990803/launch-editor/blob/master/packages/launch-editor-middleware/index.js
|
|
221
|
+
launchEditor(frame.file)
|
|
222
|
+
res.statusCode = 200
|
|
223
|
+
res.end('Stack frame opened in editor')
|
|
224
|
+
} catch (e) {
|
|
225
|
+
console.error('Failed to parse stack frame:', e)
|
|
226
|
+
res.statusCode = 400
|
|
227
|
+
return res.end('Invalid stack frame JSON')
|
|
228
|
+
}
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
return
|
|
232
|
+
}
|
|
192
233
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
234
|
+
// this is the actual Metro middleware that handles bundle requests
|
|
235
|
+
await (middleware as any)(req, res, next)
|
|
236
|
+
} catch (error) {
|
|
237
|
+
// TODO: handle errors from Metro middleware?
|
|
238
|
+
console.error('Metro middleware error:', error)
|
|
239
|
+
next()
|
|
240
|
+
}
|
|
197
241
|
} else {
|
|
198
|
-
//
|
|
199
|
-
|
|
242
|
+
// Metro not ready yet, pass through
|
|
243
|
+
next()
|
|
200
244
|
}
|
|
201
245
|
})
|
|
202
246
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metroPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/metroPlugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAOxC,OAAO,KAAK,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,OAAO,CAAA;AAMtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAIjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;AAC3D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;AAEzD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,CAAC,EAAE,kBAAkB,CAAA;IACzB,sBAAsB,CAAC,EACnB,gBAAgB,GAChB,CAAC,CAAC,aAAa,EAAE,gBAAgB,KAAK,gBAAgB,CAAC,CAAA;IAC3D;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,kDAAkD;IAClD,WAAW,CAAC,EAAE,gBAAgB,CAAA;IAC9B,oBAAoB,CAAC,EAAE,CAAC,aAAa,EAAE,gBAAgB,KAAK,gBAAgB,CAAA;IAC5E;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"metroPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/metroPlugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAOxC,OAAO,KAAK,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,OAAO,CAAA;AAMtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAIjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;AAC3D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;AAEzD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,CAAC,EAAE,kBAAkB,CAAA;IACzB,sBAAsB,CAAC,EACnB,gBAAgB,GAChB,CAAC,CAAC,aAAa,EAAE,gBAAgB,KAAK,gBAAgB,CAAC,CAAA;IAC3D;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,kDAAkD;IAClD,WAAW,CAAC,EAAE,gBAAgB,CAAA;IAC9B,oBAAoB,CAAC,EAAE,CAAC,aAAa,EAAE,gBAAgB,KAAK,gBAAgB,CAAA;IAC5E;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,YAAY,CA4L1E"}
|