@modern-js/plugin-devtools 0.0.0-next-20240516080418 → 0.0.0-next-20240522073546

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/cli.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { AppTools, CliPlugin } from '@modern-js/app-tools';
2
2
  import { ClientDefinition } from '@modern-js/devtools-kit/node';
3
- import { DevtoolsPluginOptions } from './config';
3
+ import { DevtoolsPluginOptions } from './options';
4
4
  export type { DevtoolsPluginOptions };
5
5
  export type DevtoolsPlugin = CliPlugin<AppTools> & {
6
6
  setClientDefinition: (def: ClientDefinition) => void;
package/dist/cli.js CHANGED
@@ -35,14 +35,27 @@ module.exports = __toCommonJS(cli_exports);
35
35
  var import_http = __toESM(require("http"));
36
36
  var import_path = __toESM(require("path"));
37
37
  var import_assert = __toESM(require("assert"));
38
+ var import_url = require("url");
39
+ var import_lodash = __toESM(require("@modern-js/utils/lodash"));
38
40
  var import_utils = require("@modern-js/utils");
39
- var import_serve_static = __toESM(require("serve-static"));
41
+ var import_hono = require("hono");
42
+ var import_node_server = require("@hono/node-server");
43
+ var import_serve_static = require("@hono/node-server/serve-static");
40
44
  var import_node = require("@modern-js/devtools-kit/node");
41
- var import_config = require("./config");
45
+ var import_valtio = require("valtio");
46
+ var import_options = require("./options");
42
47
  var import_rpc = require("./rpc");
43
48
  var import_socket = require("./utils/socket");
49
+ var import_config = require("./utils/config");
44
50
  const devtoolsPlugin = (inlineOptions = {}) => {
45
- const ctx = (0, import_config.resolveContext)(inlineOptions);
51
+ const ctx = (0, import_valtio.proxy)((0, import_options.resolveContext)(inlineOptions));
52
+ let watcher = null;
53
+ const closeWatcher = () => {
54
+ if (!watcher)
55
+ return;
56
+ watcher.close();
57
+ watcher = null;
58
+ };
46
59
  return {
47
60
  name: "@modern-js/plugin-devtools",
48
61
  usePlugins: [],
@@ -59,15 +72,39 @@ const devtoolsPlugin = (inlineOptions = {}) => {
59
72
  });
60
73
  const rpc = await (0, import_rpc.setupClientConnection)({
61
74
  api,
62
- server: socketServer,
63
- def: ctx.def
75
+ ctx,
76
+ server: socketServer
64
77
  });
65
78
  return {
66
- prepare: rpc.hooks.prepare,
79
+ async prepare() {
80
+ await rpc.hooks.prepare();
81
+ const appConfig = api.useConfigContext();
82
+ const appCtx = api.useAppContext();
83
+ const { devtools: options = {} } = appConfig;
84
+ (0, import_options.updateContext)(ctx, options);
85
+ const watcher2 = import_utils.chokidar.watch((0, import_config.getConfigFilenames)(), {
86
+ cwd: appCtx.appDirectory,
87
+ ignorePermissionErrors: true
88
+ });
89
+ const refreshStoragePreset = async () => {
90
+ const configs = await (0, import_config.loadConfigFiles)(appCtx.appDirectory);
91
+ if (!configs)
92
+ return;
93
+ ctx.storagePresets = [];
94
+ (0, import_options.updateContext)(ctx, ...configs);
95
+ };
96
+ watcher2.on("add", refreshStoragePreset);
97
+ watcher2.on("change", refreshStoragePreset);
98
+ watcher2.on("unlink", refreshStoragePreset);
99
+ },
67
100
  modifyFileSystemRoutes: rpc.hooks.modifyFileSystemRoutes,
68
101
  beforeRestart() {
102
+ closeWatcher();
69
103
  return new Promise((resolve, reject) => httpServer.instance.close((err) => err ? reject(err) : resolve()));
70
104
  },
105
+ beforeExit() {
106
+ closeWatcher();
107
+ },
71
108
  modifyServerRoutes({ routes }) {
72
109
  routes.push({
73
110
  urlPath: "/sw-proxy.js",
@@ -79,13 +116,18 @@ const devtoolsPlugin = (inlineOptions = {}) => {
79
116
  routes
80
117
  };
81
118
  },
82
- config() {
83
- var _api_useConfigContext_devtools;
84
- const config = (_api_useConfigContext_devtools = api.useConfigContext().devtools) !== null && _api_useConfigContext_devtools !== void 0 ? _api_useConfigContext_devtools : {};
85
- Object.assign(ctx, (0, import_config.resolveContext)(ctx, config));
119
+ async config() {
86
120
  import_utils.logger.info(`${ctx.def.name.formalName} DevTools is enabled`);
87
121
  const swProxyEntry = require.resolve("@modern-js/devtools-client/sw-proxy");
88
- const serializedOptions = JSON.stringify(ctx);
122
+ const clientOptions = import_lodash.default.pick(ctx, [
123
+ "def",
124
+ "endpoint",
125
+ "dataSource"
126
+ ]);
127
+ Object.assign(clientOptions, {
128
+ __keep: true
129
+ });
130
+ const serializedOptions = JSON.stringify(clientOptions);
89
131
  const tags = [
90
132
  {
91
133
  tag: "script",
@@ -140,11 +182,20 @@ const devtoolsPlugin = (inlineOptions = {}) => {
140
182
  devServer: {
141
183
  proxy: {
142
184
  [import_node.ROUTE_BASENAME]: {
143
- target: `http://localhost:${httpServer.port}`,
185
+ target: `http://127.0.0.1:${httpServer.port}`,
144
186
  pathRewrite: {
145
187
  [`^${import_node.ROUTE_BASENAME}`]: ""
146
188
  },
147
- ws: true
189
+ ws: true,
190
+ onProxyReq(proxyReq, req) {
191
+ const addrInfo = req.socket.address();
192
+ if ("address" in addrInfo) {
193
+ const { address } = addrInfo;
194
+ proxyReq.setHeader("X-Forwarded-For", address);
195
+ } else {
196
+ proxyReq.removeHeader("X-Forwarded-For");
197
+ }
198
+ }
148
199
  }
149
200
  }
150
201
  }
@@ -157,24 +208,71 @@ const devtoolsPlugin = (inlineOptions = {}) => {
157
208
  };
158
209
  var cli_default = devtoolsPlugin;
159
210
  const setupHttpServer = async () => {
211
+ const app = new import_hono.Hono();
160
212
  const port = await (0, import_utils.getPort)(8782, {
161
213
  slient: true
162
214
  });
163
215
  const clientServeDir = import_path.default.resolve(require.resolve("@modern-js/devtools-client/package.json"), "../dist");
164
- const serveMiddleware = (0, import_serve_static.default)(clientServeDir);
165
- const instance = import_http.default.createServer((req, res) => {
166
- const usePageNotFound = () => {
167
- res.write("404");
168
- res.statusCode = 404;
169
- res.end();
170
- };
171
- const useMainRoute = () => {
172
- req.url = "/html/client/index.html";
173
- serveMiddleware(req, res, usePageNotFound);
174
- };
175
- serveMiddleware(req, res, useMainRoute);
216
+ const handleCookieApi = async (c) => {
217
+ const raw = c.req.header("Cookie");
218
+ const { parse } = await import("cookie-es");
219
+ const cookies = raw ? parse(raw) : {};
220
+ const body = await c.req.json().catch(() => null);
221
+ if (body === null || body === void 0 ? void 0 : body.setCookies) {
222
+ const { setCookies } = body;
223
+ (0, import_assert.default)(typeof setCookies === "object", "setCookies should be object");
224
+ for (const [k, v] of Object.entries(setCookies)) {
225
+ (0, import_assert.default)(typeof v === "string");
226
+ const expires = new Date(Date.now() + 30 * 24 * 36e5).toUTCString();
227
+ cookies[k] = v;
228
+ c.header("Set-Cookie", `${k}=${v}; Expires=${expires}; Path=/`, {
229
+ append: true
230
+ });
231
+ }
232
+ }
233
+ return c.json({
234
+ cookies
235
+ });
236
+ };
237
+ app.get("/api/cookies", handleCookieApi);
238
+ app.post("/api/cookies", handleCookieApi);
239
+ app.use(
240
+ "/static/*",
241
+ // Workaround for https://github.com/honojs/node-server/blob/dd0e0cd160b0b8f18abbcb28c5f5c39b72105d98/src/serve-static.ts#L56
242
+ (0, import_serve_static.serveStatic)({
243
+ root: import_path.default.relative(process.cwd(), clientServeDir)
244
+ })
245
+ );
246
+ app.get(":filename{.+\\.hot-update\\.\\w+$}", async (c) => {
247
+ if (process.env.NODE_ENV !== "development") {
248
+ return c.text("Not found", 404);
249
+ }
250
+ const filename = c.req.param("filename");
251
+ const target = new import_url.URL(filename, "http://127.0.0.1:8780");
252
+ const { body, headers, status } = await fetch(target.href);
253
+ const newResp = c.newResponse(body, {
254
+ headers,
255
+ status
256
+ });
257
+ if (newResp.headers.get("content-encoding") === "gzip") {
258
+ newResp.headers.delete("content-encoding");
259
+ }
260
+ return newResp;
261
+ });
262
+ app.get("*", async (c) => {
263
+ const filename = import_path.default.resolve(clientServeDir, "html/client/index.html");
264
+ const content = await import_utils.fs.readFile(filename, "utf-8");
265
+ return c.html(content);
266
+ });
267
+ const instance = (0, import_node_server.serve)({
268
+ fetch: app.fetch,
269
+ port,
270
+ hostname: "127.0.0.1",
271
+ serverOptions: {
272
+ allowHTTP1: true
273
+ }
176
274
  });
177
- instance.listen(port);
275
+ (0, import_assert.default)(instance instanceof import_http.default.Server, "instance should be http.Server");
178
276
  return {
179
277
  instance,
180
278
  port
@@ -0,0 +1,8 @@
1
+ import { DevtoolsContext } from '@modern-js/devtools-kit/node';
2
+ export interface DevtoolsPluginOptions {
3
+ enable?: boolean;
4
+ endpoint?: string;
5
+ dataSource?: string;
6
+ }
7
+ export declare const resolveContext: (...sources: Partial<DevtoolsContext>[]) => DevtoolsContext;
8
+ export declare const updateContext: (context: DevtoolsContext, ...sources: Partial<DevtoolsContext>[]) => void;
@@ -16,22 +16,21 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var config_exports = {};
20
- __export(config_exports, {
21
- resolveContext: () => resolveContext
19
+ var options_exports = {};
20
+ __export(options_exports, {
21
+ resolveContext: () => resolveContext,
22
+ updateContext: () => updateContext
22
23
  });
23
- module.exports = __toCommonJS(config_exports);
24
+ module.exports = __toCommonJS(options_exports);
24
25
  var import_node = require("@modern-js/devtools-kit/node");
25
26
  const resolveContext = (...sources) => {
26
27
  const ret = {
27
28
  enable: process.env.NODE_ENV === "development",
28
29
  dataSource: `${import_node.ROUTE_BASENAME}/rpc`,
29
30
  endpoint: import_node.ROUTE_BASENAME,
30
- def: new import_node.ClientDefinition()
31
+ def: new import_node.ClientDefinition(),
32
+ storagePresets: []
31
33
  };
32
- Object.assign(ret, {
33
- __keep: true
34
- });
35
34
  for (const opts of sources) {
36
35
  var _opts_enable;
37
36
  ret.enable = (_opts_enable = opts.enable) !== null && _opts_enable !== void 0 ? _opts_enable : ret.enable;
@@ -41,10 +40,15 @@ const resolveContext = (...sources) => {
41
40
  ret.endpoint = (_opts_endpoint = opts.endpoint) !== null && _opts_endpoint !== void 0 ? _opts_endpoint : ret.endpoint;
42
41
  var _opts_def;
43
42
  ret.def = (_opts_def = opts.def) !== null && _opts_def !== void 0 ? _opts_def : ret.def;
43
+ opts.storagePresets && ret.storagePresets.push(...opts.storagePresets);
44
44
  }
45
45
  return ret;
46
46
  };
47
+ const updateContext = (context, ...sources) => {
48
+ Object.assign(context, resolveContext(context, ...sources));
49
+ };
47
50
  // Annotate the CommonJS export names for ESM import in node:
48
51
  0 && (module.exports = {
49
- resolveContext
52
+ resolveContext,
53
+ updateContext
50
54
  });
@@ -1,11 +1,11 @@
1
- import { ClientDefinition, type ClientFunctions, type ServerFunctions } from '@modern-js/devtools-kit/node';
1
+ import { type ClientFunctions, type ServerFunctions, DevtoolsContext } from '@modern-js/devtools-kit/node';
2
2
  import type { RsbuildPlugin } from '@modern-js/uni-builder';
3
3
  import { CliPluginAPI, InjectedHooks } from '../types';
4
4
  import { SocketServer } from '../utils/socket';
5
5
  export interface SetupClientConnectionOptions {
6
6
  api: CliPluginAPI;
7
7
  server: SocketServer;
8
- def: ClientDefinition;
8
+ ctx: DevtoolsContext;
9
9
  }
10
10
  export declare const setupClientConnection: (options: SetupClientConnectionOptions) => Promise<{
11
11
  client: import("birpc").BirpcReturn<ClientFunctions, ServerFunctions>;
package/dist/rpc/index.js CHANGED
@@ -31,15 +31,96 @@ __export(rpc_exports, {
31
31
  setupClientConnection: () => setupClientConnection
32
32
  });
33
33
  module.exports = __toCommonJS(rpc_exports);
34
- var import_lodash = __toESM(require("@modern-js/utils/lodash"));
34
+ var import_path = __toESM(require("path"));
35
+ var import_buffer = require("buffer");
35
36
  var import_node = require("@modern-js/devtools-kit/node");
37
+ var import_lodash = __toESM(require("@modern-js/utils/lodash"));
36
38
  var import_birpc = require("birpc");
37
39
  var flatted = __toESM(require("flatted"));
38
- var import_p_defer = __toESM(require("p-defer"));
40
+ var import_valtio = require("valtio");
41
+ var import_utils = require("@modern-js/utils");
39
42
  var import_module = require("../utils/module");
43
+ var import_state = require("../state");
44
+ const resolveDependencies = async (rootPath) => {
45
+ const ret = {};
46
+ const resolveExprs = {
47
+ react: [
48
+ rootPath,
49
+ "react/package.json"
50
+ ],
51
+ "@modern-js/app-tools": [
52
+ rootPath,
53
+ "@modern-js/app-tools/package.json"
54
+ ],
55
+ "@edenx/app-tools": [
56
+ rootPath,
57
+ "@edenx/app-tools/package.json"
58
+ ],
59
+ webpack: [
60
+ rootPath,
61
+ "@modern-js/app-tools",
62
+ "@modern-js/uni-builder",
63
+ "@rsbuild/webpack",
64
+ "webpack/package.json"
65
+ ],
66
+ "@rspack/core": [
67
+ rootPath,
68
+ "@modern-js/uni-builder",
69
+ "@rsbuild/core",
70
+ "@rspack/core/package.json"
71
+ ],
72
+ "@rsdoctor/rspack-plugin": [
73
+ rootPath,
74
+ "@rsdoctor/rspack-plugin/package.json"
75
+ ],
76
+ "@rsdoctor/webpack-plugin": [
77
+ rootPath,
78
+ "@rsdoctor/webpack-plugin/package.json"
79
+ ],
80
+ "@web-doctor/webpack-plugin": [
81
+ rootPath,
82
+ "@web-doctor/webpack-plugin/package.json"
83
+ ],
84
+ "@web-doctor/rspack-plugin": [
85
+ rootPath,
86
+ "@web-doctor/rspack-plugin/package.json"
87
+ ],
88
+ "@web-doctor/webpack-plugin(builder)": [
89
+ rootPath,
90
+ "@edenx/builder-plugin-web-doctor",
91
+ "@web-doctor/webpack-plugin/package.json"
92
+ ],
93
+ "@web-doctor/rspack-plugin(builder)": [
94
+ rootPath,
95
+ "@edenx/builder-plugin-web-doctor",
96
+ "@web-doctor/rspack-plugin/package.json"
97
+ ],
98
+ "@rsdoctor/core": [
99
+ rootPath,
100
+ "@rsdoctor/core/package.json"
101
+ ]
102
+ };
103
+ for (const [name, expr] of Object.entries(resolveExprs)) {
104
+ try {
105
+ ret[name] = (0, import_module.requireModule)(expr).version;
106
+ } catch {
107
+ }
108
+ }
109
+ return ret;
110
+ };
111
+ const getDoctorOverview = async (ctx) => {
112
+ const manifestPath = await (0, import_node.findManifest)(ctx.distDirectory);
113
+ const json = await (0, import_node.parseManifest)(require(manifestPath));
114
+ return {
115
+ numModules: json.data.moduleGraph.modules.length,
116
+ numChunks: json.data.chunkGraph.chunks.length,
117
+ numPackages: json.data.packageGraph.packages.length,
118
+ summary: json.data.summary,
119
+ errors: json.data.errors
120
+ };
121
+ };
40
122
  const setupClientConnection = async (options) => {
41
- const { api, server, def } = options;
42
- const _fileSystemRoutesMap = {};
123
+ const { api, server, ctx } = options;
43
124
  let handleMessage = null;
44
125
  const onceConnection = new Promise((resolve) => {
45
126
  server.on("connection", (ws) => {
@@ -47,151 +128,106 @@ const setupClientConnection = async (options) => {
47
128
  ws.on("message", (data, isBinary) => handleMessage === null || handleMessage === void 0 ? void 0 : handleMessage(data, isBinary));
48
129
  });
49
130
  });
50
- const deferred = {
51
- prepare: (0, import_p_defer.default)(),
52
- builder: {
53
- context: (0, import_p_defer.default)(),
54
- config: {
55
- resolved: (0, import_p_defer.default)(),
56
- transformed: (0, import_p_defer.default)()
57
- }
58
- },
59
- bundler: {
60
- config: {
61
- resolved: (0, import_p_defer.default)(),
62
- transformed: (0, import_p_defer.default)()
131
+ if ("resolve" in import_state.$resolvers.context) {
132
+ import_state.$resolvers.context.resolve(ctx);
133
+ }
134
+ import_state.$state.context = ctx;
135
+ (0, import_valtio.subscribe)(import_state.$state, (ops) => {
136
+ clientConn.applyStateOperations.asEvent(ops);
137
+ });
138
+ const validateSafeToOpen = (filename) => {
139
+ const { appDirectory } = api.useAppContext();
140
+ const resolved = import_path.default.resolve(appDirectory, filename);
141
+ for (const preset of ctx.storagePresets) {
142
+ if (import_path.default.resolve(appDirectory, preset.filename) === resolved) {
143
+ return true;
63
144
  }
64
- },
65
- compileTimeCost: (0, import_p_defer.default)()
145
+ }
146
+ return false;
66
147
  };
67
148
  const serverFunctions = {
68
- async getFrameworkConfig() {
69
- await deferred.prepare.promise;
70
- return api.useConfigContext();
71
- },
72
- async getTransformedFrameworkConfig() {
73
- await deferred.prepare.promise;
74
- return api.useResolvedConfigContext();
75
- },
76
- async getBuilderConfig() {
77
- return deferred.builder.config.resolved.promise;
78
- },
79
- async getTransformedBuilderConfig() {
80
- return deferred.builder.config.transformed.promise;
81
- },
82
- async getBundlerConfigs() {
83
- return deferred.bundler.config.resolved.promise;
149
+ echo(content) {
150
+ return content;
84
151
  },
85
- async getTransformedBundlerConfigs() {
86
- return deferred.bundler.config.transformed.promise;
152
+ async pullExportedState() {
153
+ (0, import_node.extractSettledOperations)(import_state.$state).then((ops) => {
154
+ clientConn.applyStateOperations.asEvent(ops);
155
+ });
156
+ return import_state.$state;
87
157
  },
88
- async getAppContext() {
89
- await deferred.prepare.promise;
90
- const ctx = {
91
- ...api.useAppContext()
158
+ async createTemporaryStoragePreset() {
159
+ var _config;
160
+ const appCtx = api.useAppContext();
161
+ const basename = `${ctx.def.name.shortName}.runtime.json`;
162
+ const filename = import_path.default.resolve(appCtx.appDirectory, basename);
163
+ const id = (0, import_utils.nanoid)();
164
+ const name = `New Preset ${id.slice(0, 6)}`;
165
+ const config = {};
166
+ if (await import_utils.fs.pathExists(filename)) {
167
+ Object.assign(config, await import_utils.fs.readJSON(filename));
168
+ }
169
+ const newPreset = {
170
+ name,
171
+ id,
172
+ cookie: {},
173
+ localStorage: {},
174
+ sessionStorage: {}
92
175
  };
93
- return import_lodash.default.omit(ctx, [
94
- "builder",
95
- "serverInternalPlugins"
96
- ]);
97
- },
98
- async getFileSystemRoutes(entryName) {
99
- var _fileSystemRoutesMap_entryName;
100
- return (_fileSystemRoutesMap_entryName = _fileSystemRoutesMap[entryName]) !== null && _fileSystemRoutesMap_entryName !== void 0 ? _fileSystemRoutesMap_entryName : [];
101
- },
102
- async getBuilderContext() {
103
- const ctx = await deferred.builder.context.promise;
104
- return ctx;
176
+ (_config = config).storagePresets || (_config.storagePresets = []);
177
+ config.storagePresets.push(newPreset);
178
+ await import_utils.fs.outputJSON(filename, config, {
179
+ spaces: 2
180
+ });
181
+ return newPreset;
105
182
  },
106
- async getDependencies() {
107
- const ctx = await deferred.builder.context.promise;
108
- const ret = {};
109
- const resolveExprs = {
110
- react: [
111
- ctx.rootPath,
112
- "react/package.json"
113
- ],
114
- "@modern-js/app-tools": [
115
- ctx.rootPath,
116
- "@modern-js/app-tools/package.json"
117
- ],
118
- "@edenx/app-tools": [
119
- ctx.rootPath,
120
- "@edenx/app-tools/package.json"
121
- ],
122
- webpack: [
123
- ctx.rootPath,
124
- "@modern-js/app-tools",
125
- "@modern-js/uni-builder",
126
- "@rsbuild/webpack",
127
- "webpack/package.json"
128
- ],
129
- "@rspack/core": [
130
- ctx.rootPath,
131
- "@modern-js/uni-builder",
132
- "@rsbuild/core",
133
- "@rspack/core/package.json"
134
- ],
135
- "@rsdoctor/rspack-plugin": [
136
- ctx.rootPath,
137
- "@rsdoctor/rspack-plugin/package.json"
138
- ],
139
- "@rsdoctor/webpack-plugin": [
140
- ctx.rootPath,
141
- "@rsdoctor/webpack-plugin/package.json"
142
- ],
143
- "@web-doctor/webpack-plugin": [
144
- ctx.rootPath,
145
- "@web-doctor/webpack-plugin/package.json"
146
- ],
147
- "@web-doctor/rspack-plugin": [
148
- ctx.rootPath,
149
- "@web-doctor/rspack-plugin/package.json"
150
- ],
151
- "@web-doctor/webpack-plugin(builder)": [
152
- ctx.rootPath,
153
- "@edenx/builder-plugin-web-doctor",
154
- "@web-doctor/webpack-plugin/package.json"
155
- ],
156
- "@web-doctor/rspack-plugin(builder)": [
157
- ctx.rootPath,
158
- "@edenx/builder-plugin-web-doctor",
159
- "@web-doctor/rspack-plugin/package.json"
160
- ],
161
- "@rsdoctor/core": [
162
- ctx.rootPath,
163
- "@rsdoctor/core/package.json"
164
- ]
165
- };
166
- for (const [name, expr] of Object.entries(resolveExprs)) {
167
- try {
168
- ret[name] = (0, import_module.requireModule)(expr).version;
169
- } catch {
170
- }
183
+ async pasteStoragePreset(target) {
184
+ var _config;
185
+ const { default: clipboardy } = await import("clipboardy");
186
+ const raw = clipboardy.readSync();
187
+ const HEAD = `data:application/json;base64,`;
188
+ if (!raw.startsWith(HEAD)) {
189
+ throw new Error("Failed to parse data URL");
171
190
  }
172
- return ret;
173
- },
174
- async getCompileTimeCost() {
175
- return deferred.compileTimeCost.promise;
176
- },
177
- async getClientDefinition() {
178
- return def;
179
- },
180
- async getDoctorOverview() {
181
- const ctx = api.useAppContext();
182
- const manifestPath = await (0, import_node.findManifest)(ctx.distDirectory);
183
- const json = await (0, import_node.parseManifest)(require(manifestPath));
184
- const data = {
185
- numModules: json.data.moduleGraph.modules.length,
186
- numChunks: json.data.chunkGraph.chunks.length,
187
- numPackages: json.data.packageGraph.packages.length,
188
- summary: json.data.summary,
189
- errors: json.data.errors
190
- };
191
- return data;
191
+ const encoded = raw.slice(HEAD.length);
192
+ const preset = JSON.parse(import_buffer.Buffer.from(encoded, "base64").toString("utf-8"));
193
+ if (typeof preset !== "object" || preset === null) {
194
+ throw new Error("Failed to parse data URL");
195
+ }
196
+ if (typeof preset.name !== "string") {
197
+ throw new Error("Failed to parse data URL");
198
+ }
199
+ const appCtx = api.useAppContext();
200
+ const filename = import_path.default.resolve(appCtx.appDirectory, target.filename);
201
+ const config = {};
202
+ if (await import_utils.fs.pathExists(filename)) {
203
+ Object.assign(config, await import_utils.fs.readJSON(filename));
204
+ }
205
+ (_config = config).storagePresets || (_config.storagePresets = []);
206
+ const diff = import_lodash.default.pick(preset, [
207
+ "cookie",
208
+ "localStorage",
209
+ "sessionStorage"
210
+ ]);
211
+ const matched = import_lodash.default.find(config.storagePresets, {
212
+ id: target.id
213
+ });
214
+ if (matched) {
215
+ import_lodash.default.merge(matched, diff);
216
+ } else {
217
+ config.storagePresets.push(preset);
218
+ }
219
+ await import_utils.fs.outputJSON(filename, config, {
220
+ spaces: 2
221
+ });
192
222
  },
193
- echo(content) {
194
- return content;
223
+ async open(filename) {
224
+ const name = import_path.default.resolve(api.useAppContext().appDirectory, filename);
225
+ const validated = validateSafeToOpen(name);
226
+ if (!validated) {
227
+ throw new Error("Failed to validate the file.");
228
+ }
229
+ const { default: open } = await import("open");
230
+ await open(name);
195
231
  }
196
232
  };
197
233
  const clientRpcOptions = {
@@ -199,16 +235,27 @@ const setupClientConnection = async (options) => {
199
235
  on: (cb) => handleMessage = cb,
200
236
  serialize: (v) => flatted.stringify([
201
237
  v
202
- ]),
203
- deserialize: (v) => flatted.parse(v.toString())[0]
238
+ ], import_node.replacer),
239
+ deserialize: (v) => {
240
+ const msg = flatted.parse(v.toString(), import_node.reviver)[0];
241
+ return msg;
242
+ }
204
243
  };
205
244
  const clientConn = (0, import_birpc.createBirpc)(serverFunctions, clientRpcOptions);
206
245
  const hooks = {
207
246
  prepare() {
208
- deferred.prepare.resolve();
247
+ const frameworkContext = {
248
+ ...api.useAppContext(),
249
+ builder: null,
250
+ serverInternalPlugins: null
251
+ };
252
+ import_state.$resolvers.framework.context.resolve(frameworkContext);
253
+ import_state.$resolvers.framework.config.resolved.resolve(api.useConfigContext());
254
+ import_state.$resolvers.framework.config.transformed.resolve(api.useResolvedConfigContext());
255
+ getDoctorOverview(frameworkContext).then((doctor) => import_state.$resolvers.doctor.resolve(doctor)).catch(() => import_state.$resolvers.doctor.resolve(void 0));
209
256
  },
210
257
  modifyFileSystemRoutes({ entrypoint, routes }) {
211
- _fileSystemRoutesMap[entrypoint.entryName] = import_lodash.default.cloneDeep(routes);
258
+ import_state.$state.fileSystemRoutes[entrypoint.entryName] = import_lodash.default.cloneDeep(routes);
212
259
  return {
213
260
  entrypoint,
214
261
  routes
@@ -218,17 +265,20 @@ const setupClientConnection = async (options) => {
218
265
  const builderPlugin = {
219
266
  name: "builder-plugin-devtools",
220
267
  setup(api2) {
221
- deferred.builder.context.resolve(import_lodash.default.cloneDeep(api2.context));
268
+ import_state.$resolvers.builder.context.resolve(api2.context);
269
+ resolveDependencies(api2.context.rootPath).then((deps) => {
270
+ import_state.$state.dependencies = deps;
271
+ });
222
272
  api2.modifyBundlerChain(() => {
223
- deferred.builder.config.resolved.resolve(import_lodash.default.cloneDeep(api2.getRsbuildConfig()));
224
- deferred.builder.config.transformed.resolve(import_lodash.default.cloneDeep(api2.getNormalizedConfig()));
273
+ import_state.$resolvers.builder.config.resolved.resolve(import_lodash.default.cloneDeep(api2.getRsbuildConfig()));
274
+ import_state.$resolvers.builder.config.transformed.resolve(import_lodash.default.cloneDeep(api2.getNormalizedConfig()));
225
275
  });
226
276
  const expectBundlerNum = import_lodash.default.castArray(api2.context.targets).length;
227
277
  const bundlerConfigs = [];
228
278
  const handleBundlerConfig = (config) => {
229
279
  bundlerConfigs.push(config);
230
280
  if (bundlerConfigs.length >= expectBundlerNum) {
231
- deferred.bundler.config.resolved.resolve(import_lodash.default.cloneDeep(bundlerConfigs));
281
+ import_state.$state.bundler.configs.resolved = import_lodash.default.cloneDeep(bundlerConfigs);
232
282
  }
233
283
  };
234
284
  if (api2.context.bundlerType === "webpack") {
@@ -241,17 +291,21 @@ const setupClientConnection = async (options) => {
241
291
  });
242
292
  }
243
293
  api2.onBeforeCreateCompiler(({ bundlerConfigs: bundlerConfigs2 }) => {
244
- deferred.bundler.config.transformed.resolve(import_lodash.default.cloneDeep(bundlerConfigs2));
294
+ import_state.$resolvers.bundler.configs.transformed.resolve(import_lodash.default.cloneDeep(bundlerConfigs2));
245
295
  });
246
296
  let buildStartedAt = NaN;
247
297
  api2.onAfterCreateCompiler(() => {
248
298
  buildStartedAt = Date.now();
249
299
  });
250
300
  api2.onDevCompileDone(() => {
251
- deferred.compileTimeCost.resolve(Date.now() - buildStartedAt);
301
+ import_state.$resolvers.performance.resolve({
302
+ compileDuration: Date.now() - buildStartedAt
303
+ });
252
304
  });
253
305
  api2.onAfterBuild(() => {
254
- deferred.compileTimeCost.resolve(Date.now() - buildStartedAt);
306
+ import_state.$resolvers.performance.resolve({
307
+ compileDuration: Date.now() - buildStartedAt
308
+ });
255
309
  });
256
310
  }
257
311
  };
@@ -0,0 +1,4 @@
1
+ import { ServerExportedStateResolvers } from '@modern-js/devtools-kit/node';
2
+ export declare const $serverExportedState: import("@modern-js/devtools-kit/node").ServerExportedStateResult;
3
+ export declare const $resolvers: ServerExportedStateResolvers;
4
+ export declare const $state: import("@modern-js/devtools-kit/node").ServerExportedState;
package/dist/state.js ADDED
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var state_exports = {};
20
+ __export(state_exports, {
21
+ $resolvers: () => $resolvers,
22
+ $serverExportedState: () => $serverExportedState,
23
+ $state: () => $state
24
+ });
25
+ module.exports = __toCommonJS(state_exports);
26
+ var import_valtio = require("valtio");
27
+ var import_node = require("@modern-js/devtools-kit/node");
28
+ const $serverExportedState = (0, import_node.createServerExportedState)();
29
+ const $resolvers = $serverExportedState.resolvers;
30
+ const $state = (0, import_valtio.proxy)($serverExportedState.state);
31
+ // Annotate the CommonJS export names for ESM import in node:
32
+ 0 && (module.exports = {
33
+ $resolvers,
34
+ $serverExportedState,
35
+ $state
36
+ });
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var common_exports = {};
16
+ module.exports = __toCommonJS(common_exports);
@@ -0,0 +1,4 @@
1
+ import { StoragePresetWithIdent } from '@modern-js/devtools-kit/node';
2
+ export interface DevtoolsConfig {
3
+ storagePresets?: StoragePresetWithIdent[];
4
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var config_exports = {};
16
+ module.exports = __toCommonJS(config_exports);
@@ -0,0 +1,2 @@
1
+ export type * from './common';
2
+ export type * from './config';
@@ -0,0 +1,8 @@
1
+ import { DevtoolsContext, StoragePresetContext } from '@modern-js/devtools-kit';
2
+ export declare function getConfigFilenames(dir?: string): string[];
3
+ /** Resolve all config files from target directory upward to the root path. */
4
+ export declare function resolveConfigFiles(dir?: string): Promise<string[]>;
5
+ export declare function loadConfigFile(filename: string): Promise<{
6
+ storagePresets: StoragePresetContext[];
7
+ } | null>;
8
+ export declare function loadConfigFiles(dir?: string): Promise<Partial<DevtoolsContext>[] | null>;
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var config_exports = {};
30
+ __export(config_exports, {
31
+ getConfigFilenames: () => getConfigFilenames,
32
+ loadConfigFile: () => loadConfigFile,
33
+ loadConfigFiles: () => loadConfigFiles,
34
+ resolveConfigFiles: () => resolveConfigFiles
35
+ });
36
+ module.exports = __toCommonJS(config_exports);
37
+ var import_path = __toESM(require("path"));
38
+ var import_fs_extra = __toESM(require("@modern-js/utils/fs-extra"));
39
+ var import_utils = require("@modern-js/utils");
40
+ const CONFIG_FILENAME = "modern.runtime.json";
41
+ function getConfigFilenames(dir = process.cwd()) {
42
+ const files = [];
43
+ let curr = dir;
44
+ while (import_path.default.dirname(curr) !== curr) {
45
+ files.push(import_path.default.join(curr, CONFIG_FILENAME));
46
+ curr = import_path.default.dirname(curr);
47
+ }
48
+ return files;
49
+ }
50
+ async function resolveConfigFiles(dir = process.cwd()) {
51
+ const files = getConfigFilenames(dir);
52
+ const ret = [];
53
+ await Promise.all(files.map(async (file) => await import_fs_extra.default.pathExists(file) && ret.push(file)));
54
+ return ret;
55
+ }
56
+ async function loadConfigFile(filename) {
57
+ const storagePresets = [];
58
+ try {
59
+ const config = await import_fs_extra.default.readJSON(filename);
60
+ config.storagePresets && storagePresets.push(...config.storagePresets);
61
+ } catch (e) {
62
+ import_utils.logger.error(e);
63
+ return null;
64
+ }
65
+ const presets = [];
66
+ let _validated = true;
67
+ for (const preset of storagePresets) {
68
+ if (typeof preset.id !== "string") {
69
+ preset.id = (0, import_utils.nanoid)();
70
+ _validated = false;
71
+ }
72
+ presets.push(preset);
73
+ }
74
+ if (!_validated) {
75
+ await import_fs_extra.default.outputJSON(filename, {
76
+ storagePresets: presets
77
+ }, {
78
+ spaces: 2
79
+ });
80
+ return null;
81
+ }
82
+ const ret = [];
83
+ for (const preset of presets) {
84
+ ret.push({
85
+ ...preset,
86
+ filename
87
+ });
88
+ }
89
+ return {
90
+ storagePresets: ret
91
+ };
92
+ }
93
+ async function loadConfigFiles(dir = process.cwd()) {
94
+ const filenames = await resolveConfigFiles(dir);
95
+ const resolved = await Promise.all(filenames.map(loadConfigFile));
96
+ const ret = [];
97
+ for (const config of resolved) {
98
+ if (config) {
99
+ ret.push(config);
100
+ } else {
101
+ return null;
102
+ }
103
+ }
104
+ return ret;
105
+ }
106
+ // Annotate the CommonJS export names for ESM import in node:
107
+ 0 && (module.exports = {
108
+ getConfigFilenames,
109
+ loadConfigFile,
110
+ loadConfigFiles,
111
+ resolveConfigFiles
112
+ });
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "0.0.0-next-20240516080418",
18
+ "version": "0.0.0-next-20240522073546",
19
19
  "jsnext:source": "./src/index.ts",
20
20
  "types": "./dist/index.d.ts",
21
21
  "main": "./dist/index.js",
@@ -43,34 +43,38 @@
43
43
  }
44
44
  },
45
45
  "dependencies": {
46
+ "@hono/node-server": "^1.8.2",
46
47
  "birpc": "0.2.13",
48
+ "clipboardy": "^4.0.0",
49
+ "cookie-es": "^1.0.0",
47
50
  "flatted": "^3.2.9",
48
- "serve-static": "^1.14.1",
51
+ "hono": "^3.12.2",
52
+ "open": "^10.1.0",
49
53
  "p-defer": "^3.0.0",
50
- "ws": "^8.13.0",
51
54
  "ufo": "^1.3.0",
52
- "@modern-js/devtools-kit": "0.0.0-next-20240516080418",
53
- "@modern-js/utils": "0.0.0-next-20240516080418",
54
- "@modern-js/devtools-client": "0.0.0-next-20240516080418"
55
+ "valtio": "^1.11.1",
56
+ "ws": "^8.13.0",
57
+ "@modern-js/devtools-client": "0.0.0-next-20240522073546",
58
+ "@modern-js/devtools-kit": "0.0.0-next-20240522073546",
59
+ "@modern-js/utils": "0.0.0-next-20240522073546"
55
60
  },
56
61
  "devDependencies": {
57
- "@types/serve-static": "^1.13.10",
58
62
  "@swc/helpers": "0.5.3",
59
63
  "@types/node": "^14",
60
64
  "@types/ws": "^8.5.5",
61
65
  "type-fest": "^4.1.0",
62
66
  "typescript": "^5",
63
- "@modern-js/app-tools": "0.0.0-next-20240516080418",
64
- "@modern-js/core": "0.0.0-next-20240516080418",
65
- "@modern-js/runtime": "0.0.0-next-20240516080418",
66
- "@modern-js/module-tools": "0.0.0-next-20240516080418",
67
- "@modern-js/server-core": "0.0.0-next-20240516080418",
68
- "@modern-js/uni-builder": "0.0.0-next-20240516080418",
69
- "@modern-js/types": "0.0.0-next-20240516080418",
70
- "@scripts/build": "0.0.0-next-20240516080418"
67
+ "@modern-js/app-tools": "0.0.0-next-20240522073546",
68
+ "@modern-js/core": "0.0.0-next-20240522073546",
69
+ "@modern-js/module-tools": "0.0.0-next-20240522073546",
70
+ "@modern-js/runtime": "0.0.0-next-20240522073546",
71
+ "@modern-js/server-core": "0.0.0-next-20240522073546",
72
+ "@modern-js/types": "0.0.0-next-20240522073546",
73
+ "@modern-js/uni-builder": "0.0.0-next-20240522073546",
74
+ "@scripts/build": "0.0.0-next-20240522073546"
71
75
  },
72
76
  "peerDependencies": {
73
- "@modern-js/runtime": "0.0.0-next-20240516080418"
77
+ "@modern-js/runtime": "0.0.0-next-20240522073546"
74
78
  },
75
79
  "peerDependenciesMeta": {
76
80
  "@modern-js/runtime": {
package/dist/config.d.ts DELETED
@@ -1,11 +0,0 @@
1
- import { ClientDefinition } from '@modern-js/devtools-kit/node';
2
- import type { RequiredDeep } from 'type-fest';
3
- export interface DevtoolsPluginOptions {
4
- enable?: boolean;
5
- endpoint?: string;
6
- dataSource?: string;
7
- }
8
- export interface DevtoolsContext extends RequiredDeep<DevtoolsPluginOptions> {
9
- def: ClientDefinition;
10
- }
11
- export declare const resolveContext: (...sources: Partial<DevtoolsContext>[]) => DevtoolsContext;
File without changes
File without changes