@bleedingdev/modern-js-plugin 3.9.0-ultramodern.8 → 3.9.3-ultramodern.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/cjs/cli/index.js +21 -2
  2. package/dist/cjs/cli/run/config/createLoadedConfig.js +17 -8
  3. package/dist/cjs/cli/run/create.js +6 -1
  4. package/dist/cjs/cli/run/utils/commander.js +7 -5
  5. package/dist/cjs/cli/run/utils/debug.js +2 -2
  6. package/dist/cjs/runtime/api.js +2 -0
  7. package/dist/cjs/runtime/hooks.js +16 -0
  8. package/dist/cjs/server/api.js +2 -2
  9. package/dist/esm/cli/index.mjs +1 -0
  10. package/dist/esm/cli/run/config/createLoadedConfig.mjs +17 -8
  11. package/dist/esm/cli/run/create.mjs +6 -1
  12. package/dist/esm/cli/run/utils/commander.mjs +4 -2
  13. package/dist/esm/cli/run/utils/debug.mjs +1 -1
  14. package/dist/esm/runtime/api.mjs +2 -0
  15. package/dist/esm/runtime/hooks.mjs +17 -1
  16. package/dist/esm/server/api.mjs +1 -1
  17. package/dist/esm-node/cli/index.mjs +1 -0
  18. package/dist/esm-node/cli/run/config/createLoadedConfig.mjs +17 -8
  19. package/dist/esm-node/cli/run/create.mjs +6 -1
  20. package/dist/esm-node/cli/run/utils/commander.mjs +4 -2
  21. package/dist/esm-node/cli/run/utils/debug.mjs +1 -1
  22. package/dist/esm-node/runtime/api.mjs +2 -0
  23. package/dist/esm-node/runtime/hooks.mjs +17 -1
  24. package/dist/esm-node/server/api.mjs +1 -1
  25. package/dist/types/cli/api.d.ts +1 -1
  26. package/dist/types/cli/hooks.d.ts +28 -37
  27. package/dist/types/cli/index.d.ts +6 -0
  28. package/dist/types/cli/run/config/createLoadedConfig.d.ts +5 -1
  29. package/dist/types/cli/run/create.d.ts +4 -3
  30. package/dist/types/cli/run/index.d.ts +5 -4
  31. package/dist/types/cli/run/types.d.ts +4 -9
  32. package/dist/types/cli/run/utils/commander.d.ts +3 -2
  33. package/dist/types/cli/run/utils/createFileWatcher.d.ts +3 -2
  34. package/dist/types/cli/run/utils/debug.d.ts +1 -1
  35. package/dist/types/index.d.ts +1 -1
  36. package/dist/types/manager.d.ts +1 -1
  37. package/dist/types/runtime/index.d.ts +1 -1
  38. package/dist/types/server/api.d.ts +1 -1
  39. package/dist/types/server/hooks.d.ts +6 -5
  40. package/dist/types/server/run/create.d.ts +3 -2
  41. package/dist/types/server/run/index.d.ts +2 -5
  42. package/dist/types/server/run/types.d.ts +1 -1
  43. package/dist/types/types/cli/context.d.ts +1 -1
  44. package/dist/types/types/cli/hooks.d.ts +6 -7
  45. package/dist/types/types/cli/index.d.ts +1 -1
  46. package/dist/types/types/plugin.d.ts +3 -3
  47. package/dist/types/types/runtime/api.d.ts +3 -1
  48. package/dist/types/types/runtime/hooks.d.ts +36 -1
  49. package/dist/types/types/server/context.d.ts +1 -1
  50. package/package.json +18 -16
@@ -29,29 +29,42 @@ var __webpack_exports__ = {};
29
29
  __webpack_require__.r(__webpack_exports__);
30
30
  __webpack_require__.d(__webpack_exports__, {
31
31
  cli: ()=>index_js_namespaceObject.cli,
32
+ createAsyncHook: ()=>external_hooks_js_namespaceObject.createAsyncHook,
33
+ createAsyncInterruptHook: ()=>external_hooks_js_namespaceObject.createAsyncInterruptHook,
34
+ createAsyncPipelineHook: ()=>external_hooks_js_namespaceObject.createAsyncPipelineHook,
32
35
  createCli: ()=>index_js_namespaceObject.createCli,
36
+ createCollectAsyncHook: ()=>external_hooks_js_namespaceObject.createCollectAsyncHook,
37
+ createCollectSyncHook: ()=>external_hooks_js_namespaceObject.createCollectSyncHook,
33
38
  createConfigOptions: ()=>create_js_namespaceObject.createConfigOptions,
34
39
  createContext: ()=>external_context_js_namespaceObject.createContext,
35
40
  createLoadedConfig: ()=>index_js_namespaceObject.createLoadedConfig,
36
41
  createStorybookOptions: ()=>create_js_namespaceObject.createStorybookOptions,
42
+ createSyncHook: ()=>external_hooks_js_namespaceObject.createSyncHook,
37
43
  initAppContext: ()=>external_context_js_namespaceObject.initAppContext,
38
44
  initAppDir: ()=>index_js_namespaceObject.initAppDir,
39
- initHooks: ()=>external_hooks_js_namespaceObject.initHooks,
45
+ initHooks: ()=>external_hooks_js_namespaceObject_1.initHooks,
40
46
  initPluginAPI: ()=>external_api_js_namespaceObject.initPluginAPI,
41
47
  mergeConfig: ()=>mergeConfig_js_namespaceObject.mergeConfig
42
48
  });
49
+ const external_hooks_js_namespaceObject = require("../hooks.js");
43
50
  const external_api_js_namespaceObject = require("./api.js");
44
51
  const external_context_js_namespaceObject = require("./context.js");
45
- const external_hooks_js_namespaceObject = require("./hooks.js");
52
+ const external_hooks_js_namespaceObject_1 = require("./hooks.js");
46
53
  const index_js_namespaceObject = require("./run/index.js");
47
54
  const create_js_namespaceObject = require("./run/create.js");
48
55
  const mergeConfig_js_namespaceObject = require("./run/utils/mergeConfig.js");
49
56
  exports.cli = __webpack_exports__.cli;
57
+ exports.createAsyncHook = __webpack_exports__.createAsyncHook;
58
+ exports.createAsyncInterruptHook = __webpack_exports__.createAsyncInterruptHook;
59
+ exports.createAsyncPipelineHook = __webpack_exports__.createAsyncPipelineHook;
50
60
  exports.createCli = __webpack_exports__.createCli;
61
+ exports.createCollectAsyncHook = __webpack_exports__.createCollectAsyncHook;
62
+ exports.createCollectSyncHook = __webpack_exports__.createCollectSyncHook;
51
63
  exports.createConfigOptions = __webpack_exports__.createConfigOptions;
52
64
  exports.createContext = __webpack_exports__.createContext;
53
65
  exports.createLoadedConfig = __webpack_exports__.createLoadedConfig;
54
66
  exports.createStorybookOptions = __webpack_exports__.createStorybookOptions;
67
+ exports.createSyncHook = __webpack_exports__.createSyncHook;
55
68
  exports.initAppContext = __webpack_exports__.initAppContext;
56
69
  exports.initAppDir = __webpack_exports__.initAppDir;
57
70
  exports.initHooks = __webpack_exports__.initHooks;
@@ -59,11 +72,17 @@ exports.initPluginAPI = __webpack_exports__.initPluginAPI;
59
72
  exports.mergeConfig = __webpack_exports__.mergeConfig;
60
73
  for(var __rspack_i in __webpack_exports__)if (-1 === [
61
74
  "cli",
75
+ "createAsyncHook",
76
+ "createAsyncInterruptHook",
77
+ "createAsyncPipelineHook",
62
78
  "createCli",
79
+ "createCollectAsyncHook",
80
+ "createCollectSyncHook",
63
81
  "createConfigOptions",
64
82
  "createContext",
65
83
  "createLoadedConfig",
66
84
  "createStorybookOptions",
85
+ "createSyncHook",
67
86
  "initAppContext",
68
87
  "initAppDir",
69
88
  "initHooks",
@@ -33,14 +33,16 @@ __webpack_require__.d(__webpack_exports__, {
33
33
  const utils_namespaceObject = require("@modern-js/utils");
34
34
  const mergeConfig_js_namespaceObject = require("../utils/mergeConfig.js");
35
35
  const external_loadConfig_js_namespaceObject = require("./loadConfig.js");
36
- async function getConfigObject(config) {
37
- if ('function' == typeof config) return await config({
36
+ async function getConfigObject(config, context) {
37
+ if ('function' == typeof config) return await config(context ? {
38
+ ...context
39
+ } : {
38
40
  env: (0, utils_namespaceObject.getNodeEnv)(),
39
41
  command: (0, utils_namespaceObject.getCommand)()
40
42
  }) || {};
41
43
  return config || {};
42
44
  }
43
- async function loadLocalConfig(appDirectory, configFile) {
45
+ async function loadLocalConfig(appDirectory, configFile, context) {
44
46
  let localConfigFile = false;
45
47
  if ('string' == typeof configFile) {
46
48
  for (const ext of utils_namespaceObject.CONFIG_FILE_EXTENSIONS)if (configFile.endsWith(ext)) {
@@ -50,21 +52,28 @@ async function loadLocalConfig(appDirectory, configFile) {
50
52
  }
51
53
  if (localConfigFile) {
52
54
  const loaded = await (0, external_loadConfig_js_namespaceObject.loadConfig)(appDirectory, localConfigFile);
53
- return getConfigObject(loaded.config);
55
+ return getConfigObject(loaded.config, context);
54
56
  }
55
57
  return null;
56
58
  }
57
- async function createLoadedConfig(appDirectory, configFilePath, otherConfig) {
59
+ async function createLoadedConfig(appDirectory, configFilePath, otherConfig, context) {
60
+ const evaluationContext = context ? {
61
+ ...context
62
+ } : void 0;
63
+ const shouldLoadLocal = evaluationContext ? [
64
+ 'dev',
65
+ 'start'
66
+ ].includes(evaluationContext.command) : void 0;
58
67
  const configFile = (0, external_loadConfig_js_namespaceObject.getConfigFilePath)(appDirectory, configFilePath);
59
68
  const loaded = await (0, external_loadConfig_js_namespaceObject.loadConfig)(appDirectory, configFile);
60
69
  if (!loaded.config && !loaded.pkgConfig) {
61
70
  utils_namespaceObject.logger.warn("Can not find any config file in the current project, please check if you have a correct config file.");
62
71
  utils_namespaceObject.logger.warn(`Current project path: ${utils_namespaceObject.chalk.yellow(appDirectory)}`);
63
72
  }
64
- const config = await getConfigObject(loaded.config);
73
+ const config = await getConfigObject(loaded.config, evaluationContext);
65
74
  let mergedConfig = config;
66
- if ((0, utils_namespaceObject.isDevCommand)()) {
67
- const localConfig = await loadLocalConfig(appDirectory, configFile);
75
+ if (shouldLoadLocal ?? (0, utils_namespaceObject.isDevCommand)()) {
76
+ const localConfig = await loadLocalConfig(appDirectory, configFile, evaluationContext);
68
77
  if (localConfig) mergedConfig = (0, mergeConfig_js_namespaceObject.mergeConfig)([
69
78
  mergedConfig,
70
79
  localConfig
@@ -135,15 +135,20 @@ const createCli = ()=>{
135
135
  async function run(options) {
136
136
  const { appContext } = await init(options);
137
137
  await appContext.hooks.addCommand.call({
138
- program: commander_namespaceObject.program
138
+ program: (0, commander_js_namespaceObject.initCommandsMap)()
139
139
  });
140
140
  await (0, createFileWatcher_js_namespaceObject.createFileWatcher)(appContext);
141
141
  commander_namespaceObject.program.parse(process.argv);
142
142
  if (!commander_namespaceObject.program.commands?.length) utils_namespaceObject.logger.warn('No command found, please make sure you have registered plugins correctly.');
143
143
  }
144
+ function dispose() {
145
+ for (const [event, listener] of existListenerMap)process.off(event, listener);
146
+ existListenerMap.clear();
147
+ }
144
148
  return {
145
149
  init,
146
150
  run,
151
+ dispose,
147
152
  getPrevInitOptions: ()=>initOptions
148
153
  };
149
154
  };
@@ -29,23 +29,25 @@ var __webpack_exports__ = {};
29
29
  __webpack_require__.r(__webpack_exports__);
30
30
  __webpack_require__.d(__webpack_exports__, {
31
31
  initCommandsMap: ()=>initCommandsMap,
32
- program: ()=>utils_namespaceObject.program,
32
+ program: ()=>commander_namespaceObject.program,
33
33
  setProgramVersion: ()=>setProgramVersion
34
34
  });
35
- const utils_namespaceObject = require("@modern-js/utils");
35
+ const commander_namespaceObject = require("@modern-js/utils/commander");
36
36
  const setProgramVersion = (version = 'unknown')=>{
37
37
  const name = process.argv[1];
38
- utils_namespaceObject.program.name(name).usage('<command> [options]').version(version);
38
+ commander_namespaceObject.program.name(name).usage('<command> [options]');
39
+ if (commander_namespaceObject.program.version() !== version) commander_namespaceObject.program.version(version);
39
40
  };
40
41
  function initCommandsMap() {
41
- if (!utils_namespaceObject.program.hasOwnProperty('commandsMap')) Object.defineProperty(utils_namespaceObject.program, 'commandsMap', {
42
+ if (!commander_namespaceObject.program.hasOwnProperty('commandsMap')) Object.defineProperty(commander_namespaceObject.program, 'commandsMap', {
42
43
  get () {
43
44
  const map = new Map();
44
- for (const command of utils_namespaceObject.program.commands)map.set(command._name, command);
45
+ for (const command of commander_namespaceObject.program.commands)map.set(command._name, command);
45
46
  return map;
46
47
  },
47
48
  configurable: false
48
49
  });
50
+ return commander_namespaceObject.program;
49
51
  }
50
52
  exports.initCommandsMap = __webpack_exports__.initCommandsMap;
51
53
  exports.program = __webpack_exports__.program;
@@ -30,8 +30,8 @@ __webpack_require__.r(__webpack_exports__);
30
30
  __webpack_require__.d(__webpack_exports__, {
31
31
  debug: ()=>debug
32
32
  });
33
- const utils_namespaceObject = require("@modern-js/utils");
34
- const debug = (0, utils_namespaceObject.createDebugger)('plugin');
33
+ const cli_common_namespaceObject = require("@modern-js/utils/cli-common");
34
+ const debug = (0, cli_common_namespaceObject.createDebugger)('plugin');
35
35
  exports.debug = __webpack_exports__.debug;
36
36
  for(var __rspack_i in __webpack_exports__)if (-1 === [
37
37
  "debug"
@@ -73,6 +73,8 @@ function initPluginAPI({ context, plugins }) {
73
73
  getRuntimeConfig,
74
74
  config: hooks.config.tap,
75
75
  onBeforeRender: hooks.onBeforeRender.tap,
76
+ onRenderPrepared: hooks.onRenderPrepared.tap,
77
+ onRequestEnd: hooks.onRequestEnd.tap,
76
78
  wrapRoot: hooks.wrapRoot.tap,
77
79
  resolveComponent: hooks.resolveComponent.tap,
78
80
  pickContext: hooks.pickContext.tap,
@@ -32,8 +32,24 @@ __webpack_require__.d(__webpack_exports__, {
32
32
  });
33
33
  const external_hooks_js_namespaceObject = require("../hooks.js");
34
34
  function initHooks() {
35
+ const requestEnd = (0, external_hooks_js_namespaceObject.createCollectSyncHook)();
36
+ const onRequestEnd = {
37
+ tap (callback) {
38
+ requestEnd.tap((info)=>Promise.resolve().then(()=>callback(info)));
39
+ },
40
+ async call (info) {
41
+ const results = await Promise.allSettled(requestEnd.call(info));
42
+ const errors = results.flatMap((result)=>'rejected' === result.status ? [
43
+ result.reason
44
+ ] : []);
45
+ if (1 === errors.length) throw errors[0];
46
+ if (errors.length > 1) throw new AggregateError(errors, 'Request completion hooks failed');
47
+ }
48
+ };
35
49
  return {
36
50
  onBeforeRender: (0, external_hooks_js_namespaceObject.createAsyncInterruptHook)(),
51
+ onRenderPrepared: (0, external_hooks_js_namespaceObject.createAsyncHook)(),
52
+ onRequestEnd,
37
53
  wrapRoot: (0, external_hooks_js_namespaceObject.createSyncHook)(),
38
54
  resolveComponent: (0, external_hooks_js_namespaceObject.createSyncHook)(),
39
55
  pickContext: (0, external_hooks_js_namespaceObject.createSyncHook)(),
@@ -31,9 +31,9 @@ __webpack_require__.d(__webpack_exports__, {
31
31
  debug: ()=>debug,
32
32
  initPluginAPI: ()=>initPluginAPI
33
33
  });
34
- const utils_namespaceObject = require("@modern-js/utils");
34
+ const cli_common_namespaceObject = require("@modern-js/utils/cli-common");
35
35
  const lodash_namespaceObject = require("@modern-js/utils/lodash");
36
- const debug = (0, utils_namespaceObject.createDebugger)('plugin-server-v2');
36
+ const debug = (0, cli_common_namespaceObject.createDebugger)('plugin-server-v2');
37
37
  function initPluginAPI({ context, pluginManager }) {
38
38
  const { hooks, extendsHooks, plugins } = context;
39
39
  function getServerContext() {
@@ -1,3 +1,4 @@
1
+ export { createAsyncHook, createAsyncInterruptHook, createAsyncPipelineHook, createCollectAsyncHook, createCollectSyncHook, createSyncHook } from "../hooks.mjs";
1
2
  export { initPluginAPI } from "./api.mjs";
2
3
  export { createContext, initAppContext } from "./context.mjs";
3
4
  export { initHooks } from "./hooks.mjs";
@@ -1,14 +1,16 @@
1
1
  import { CONFIG_FILE_EXTENSIONS, chalk, fs, getCommand, getNodeEnv, isDevCommand, logger } from "@modern-js/utils";
2
2
  import { mergeConfig } from "../utils/mergeConfig.mjs";
3
3
  import { getConfigFilePath, loadConfig } from "./loadConfig.mjs";
4
- async function getConfigObject(config) {
5
- if ('function' == typeof config) return await config({
4
+ async function getConfigObject(config, context) {
5
+ if ('function' == typeof config) return await config(context ? {
6
+ ...context
7
+ } : {
6
8
  env: getNodeEnv(),
7
9
  command: getCommand()
8
10
  }) || {};
9
11
  return config || {};
10
12
  }
11
- async function loadLocalConfig(appDirectory, configFile) {
13
+ async function loadLocalConfig(appDirectory, configFile, context) {
12
14
  let localConfigFile = false;
13
15
  if ('string' == typeof configFile) {
14
16
  for (const ext of CONFIG_FILE_EXTENSIONS)if (configFile.endsWith(ext)) {
@@ -18,21 +20,28 @@ async function loadLocalConfig(appDirectory, configFile) {
18
20
  }
19
21
  if (localConfigFile) {
20
22
  const loaded = await loadConfig(appDirectory, localConfigFile);
21
- return getConfigObject(loaded.config);
23
+ return getConfigObject(loaded.config, context);
22
24
  }
23
25
  return null;
24
26
  }
25
- async function createLoadedConfig(appDirectory, configFilePath, otherConfig) {
27
+ async function createLoadedConfig(appDirectory, configFilePath, otherConfig, context) {
28
+ const evaluationContext = context ? {
29
+ ...context
30
+ } : void 0;
31
+ const shouldLoadLocal = evaluationContext ? [
32
+ 'dev',
33
+ 'start'
34
+ ].includes(evaluationContext.command) : void 0;
26
35
  const configFile = getConfigFilePath(appDirectory, configFilePath);
27
36
  const loaded = await loadConfig(appDirectory, configFile);
28
37
  if (!loaded.config && !loaded.pkgConfig) {
29
38
  logger.warn("Can not find any config file in the current project, please check if you have a correct config file.");
30
39
  logger.warn(`Current project path: ${chalk.yellow(appDirectory)}`);
31
40
  }
32
- const config = await getConfigObject(loaded.config);
41
+ const config = await getConfigObject(loaded.config, evaluationContext);
33
42
  let mergedConfig = config;
34
- if (isDevCommand()) {
35
- const localConfig = await loadLocalConfig(appDirectory, configFile);
43
+ if (shouldLoadLocal ?? isDevCommand()) {
44
+ const localConfig = await loadLocalConfig(appDirectory, configFile, evaluationContext);
36
45
  if (localConfig) mergedConfig = mergeConfig([
37
46
  mergedConfig,
38
47
  localConfig
@@ -101,15 +101,20 @@ const createCli = ()=>{
101
101
  async function run(options) {
102
102
  const { appContext } = await init(options);
103
103
  await appContext.hooks.addCommand.call({
104
- program: program
104
+ program: initCommandsMap()
105
105
  });
106
106
  await createFileWatcher(appContext);
107
107
  program.parse(process.argv);
108
108
  if (!program.commands?.length) logger.warn('No command found, please make sure you have registered plugins correctly.');
109
109
  }
110
+ function dispose() {
111
+ for (const [event, listener] of existListenerMap)process.off(event, listener);
112
+ existListenerMap.clear();
113
+ }
110
114
  return {
111
115
  init,
112
116
  run,
117
+ dispose,
113
118
  getPrevInitOptions: ()=>initOptions
114
119
  };
115
120
  };
@@ -1,7 +1,8 @@
1
- import { program } from "@modern-js/utils";
1
+ import { program } from "@modern-js/utils/commander";
2
2
  const setProgramVersion = (version = 'unknown')=>{
3
3
  const name = process.argv[1];
4
- program.name(name).usage('<command> [options]').version(version);
4
+ program.name(name).usage('<command> [options]');
5
+ if (program.version() !== version) program.version(version);
5
6
  };
6
7
  function initCommandsMap() {
7
8
  if (!program.hasOwnProperty('commandsMap')) Object.defineProperty(program, 'commandsMap', {
@@ -12,5 +13,6 @@ function initCommandsMap() {
12
13
  },
13
14
  configurable: false
14
15
  });
16
+ return program;
15
17
  }
16
18
  export { initCommandsMap, program, setProgramVersion };
@@ -1,3 +1,3 @@
1
- import { createDebugger } from "@modern-js/utils";
1
+ import { createDebugger } from "@modern-js/utils/cli-common";
2
2
  const debug = createDebugger('plugin');
3
3
  export { debug };
@@ -41,6 +41,8 @@ function initPluginAPI({ context, plugins }) {
41
41
  getRuntimeConfig,
42
42
  config: hooks.config.tap,
43
43
  onBeforeRender: hooks.onBeforeRender.tap,
44
+ onRenderPrepared: hooks.onRenderPrepared.tap,
45
+ onRequestEnd: hooks.onRequestEnd.tap,
44
46
  wrapRoot: hooks.wrapRoot.tap,
45
47
  resolveComponent: hooks.resolveComponent.tap,
46
48
  pickContext: hooks.pickContext.tap,
@@ -1,7 +1,23 @@
1
- import { createAsyncInterruptHook, createCollectSyncHook, createSyncHook } from "../hooks.mjs";
1
+ import { createAsyncHook, createAsyncInterruptHook, createCollectSyncHook, createSyncHook } from "../hooks.mjs";
2
2
  function initHooks() {
3
+ const requestEnd = createCollectSyncHook();
4
+ const onRequestEnd = {
5
+ tap (callback) {
6
+ requestEnd.tap((info)=>Promise.resolve().then(()=>callback(info)));
7
+ },
8
+ async call (info) {
9
+ const results = await Promise.allSettled(requestEnd.call(info));
10
+ const errors = results.flatMap((result)=>'rejected' === result.status ? [
11
+ result.reason
12
+ ] : []);
13
+ if (1 === errors.length) throw errors[0];
14
+ if (errors.length > 1) throw new AggregateError(errors, 'Request completion hooks failed');
15
+ }
16
+ };
3
17
  return {
4
18
  onBeforeRender: createAsyncInterruptHook(),
19
+ onRenderPrepared: createAsyncHook(),
20
+ onRequestEnd,
5
21
  wrapRoot: createSyncHook(),
6
22
  resolveComponent: createSyncHook(),
7
23
  pickContext: createSyncHook(),
@@ -1,4 +1,4 @@
1
- import { createDebugger } from "@modern-js/utils";
1
+ import { createDebugger } from "@modern-js/utils/cli-common";
2
2
  import { assign as lodash_assign } from "@modern-js/utils/lodash";
3
3
  const debug = createDebugger('plugin-server-v2');
4
4
  function initPluginAPI({ context, pluginManager }) {
@@ -1,4 +1,5 @@
1
1
  import "node:module";
2
+ export { createAsyncHook, createAsyncInterruptHook, createAsyncPipelineHook, createCollectAsyncHook, createCollectSyncHook, createSyncHook } from "../hooks.mjs";
2
3
  export { initPluginAPI } from "./api.mjs";
3
4
  export { createContext, initAppContext } from "./context.mjs";
4
5
  export { initHooks } from "./hooks.mjs";
@@ -2,14 +2,16 @@ import "node:module";
2
2
  import { CONFIG_FILE_EXTENSIONS, chalk, fs, getCommand, getNodeEnv, isDevCommand, logger } from "@modern-js/utils";
3
3
  import { mergeConfig } from "../utils/mergeConfig.mjs";
4
4
  import { getConfigFilePath, loadConfig } from "./loadConfig.mjs";
5
- async function getConfigObject(config) {
6
- if ('function' == typeof config) return await config({
5
+ async function getConfigObject(config, context) {
6
+ if ('function' == typeof config) return await config(context ? {
7
+ ...context
8
+ } : {
7
9
  env: getNodeEnv(),
8
10
  command: getCommand()
9
11
  }) || {};
10
12
  return config || {};
11
13
  }
12
- async function loadLocalConfig(appDirectory, configFile) {
14
+ async function loadLocalConfig(appDirectory, configFile, context) {
13
15
  let localConfigFile = false;
14
16
  if ('string' == typeof configFile) {
15
17
  for (const ext of CONFIG_FILE_EXTENSIONS)if (configFile.endsWith(ext)) {
@@ -19,21 +21,28 @@ async function loadLocalConfig(appDirectory, configFile) {
19
21
  }
20
22
  if (localConfigFile) {
21
23
  const loaded = await loadConfig(appDirectory, localConfigFile);
22
- return getConfigObject(loaded.config);
24
+ return getConfigObject(loaded.config, context);
23
25
  }
24
26
  return null;
25
27
  }
26
- async function createLoadedConfig(appDirectory, configFilePath, otherConfig) {
28
+ async function createLoadedConfig(appDirectory, configFilePath, otherConfig, context) {
29
+ const evaluationContext = context ? {
30
+ ...context
31
+ } : void 0;
32
+ const shouldLoadLocal = evaluationContext ? [
33
+ 'dev',
34
+ 'start'
35
+ ].includes(evaluationContext.command) : void 0;
27
36
  const configFile = getConfigFilePath(appDirectory, configFilePath);
28
37
  const loaded = await loadConfig(appDirectory, configFile);
29
38
  if (!loaded.config && !loaded.pkgConfig) {
30
39
  logger.warn("Can not find any config file in the current project, please check if you have a correct config file.");
31
40
  logger.warn(`Current project path: ${chalk.yellow(appDirectory)}`);
32
41
  }
33
- const config = await getConfigObject(loaded.config);
42
+ const config = await getConfigObject(loaded.config, evaluationContext);
34
43
  let mergedConfig = config;
35
- if (isDevCommand()) {
36
- const localConfig = await loadLocalConfig(appDirectory, configFile);
44
+ if (shouldLoadLocal ?? isDevCommand()) {
45
+ const localConfig = await loadLocalConfig(appDirectory, configFile, evaluationContext);
37
46
  if (localConfig) mergedConfig = mergeConfig([
38
47
  mergedConfig,
39
48
  localConfig
@@ -102,15 +102,20 @@ const createCli = ()=>{
102
102
  async function run(options) {
103
103
  const { appContext } = await init(options);
104
104
  await appContext.hooks.addCommand.call({
105
- program: program
105
+ program: initCommandsMap()
106
106
  });
107
107
  await createFileWatcher(appContext);
108
108
  program.parse(process.argv);
109
109
  if (!program.commands?.length) logger.warn('No command found, please make sure you have registered plugins correctly.');
110
110
  }
111
+ function dispose() {
112
+ for (const [event, listener] of existListenerMap)process.off(event, listener);
113
+ existListenerMap.clear();
114
+ }
111
115
  return {
112
116
  init,
113
117
  run,
118
+ dispose,
114
119
  getPrevInitOptions: ()=>initOptions
115
120
  };
116
121
  };
@@ -1,8 +1,9 @@
1
1
  import "node:module";
2
- import { program } from "@modern-js/utils";
2
+ import { program } from "@modern-js/utils/commander";
3
3
  const setProgramVersion = (version = 'unknown')=>{
4
4
  const name = process.argv[1];
5
- program.name(name).usage('<command> [options]').version(version);
5
+ program.name(name).usage('<command> [options]');
6
+ if (program.version() !== version) program.version(version);
6
7
  };
7
8
  function initCommandsMap() {
8
9
  if (!program.hasOwnProperty('commandsMap')) Object.defineProperty(program, 'commandsMap', {
@@ -13,5 +14,6 @@ function initCommandsMap() {
13
14
  },
14
15
  configurable: false
15
16
  });
17
+ return program;
16
18
  }
17
19
  export { initCommandsMap, program, setProgramVersion };
@@ -1,4 +1,4 @@
1
1
  import "node:module";
2
- import { createDebugger } from "@modern-js/utils";
2
+ import { createDebugger } from "@modern-js/utils/cli-common";
3
3
  const debug = createDebugger('plugin');
4
4
  export { debug };
@@ -42,6 +42,8 @@ function initPluginAPI({ context, plugins }) {
42
42
  getRuntimeConfig,
43
43
  config: hooks.config.tap,
44
44
  onBeforeRender: hooks.onBeforeRender.tap,
45
+ onRenderPrepared: hooks.onRenderPrepared.tap,
46
+ onRequestEnd: hooks.onRequestEnd.tap,
45
47
  wrapRoot: hooks.wrapRoot.tap,
46
48
  resolveComponent: hooks.resolveComponent.tap,
47
49
  pickContext: hooks.pickContext.tap,
@@ -1,8 +1,24 @@
1
1
  import "node:module";
2
- import { createAsyncInterruptHook, createCollectSyncHook, createSyncHook } from "../hooks.mjs";
2
+ import { createAsyncHook, createAsyncInterruptHook, createCollectSyncHook, createSyncHook } from "../hooks.mjs";
3
3
  function initHooks() {
4
+ const requestEnd = createCollectSyncHook();
5
+ const onRequestEnd = {
6
+ tap (callback) {
7
+ requestEnd.tap((info)=>Promise.resolve().then(()=>callback(info)));
8
+ },
9
+ async call (info) {
10
+ const results = await Promise.allSettled(requestEnd.call(info));
11
+ const errors = results.flatMap((result)=>'rejected' === result.status ? [
12
+ result.reason
13
+ ] : []);
14
+ if (1 === errors.length) throw errors[0];
15
+ if (errors.length > 1) throw new AggregateError(errors, 'Request completion hooks failed');
16
+ }
17
+ };
4
18
  return {
5
19
  onBeforeRender: createAsyncInterruptHook(),
20
+ onRenderPrepared: createAsyncHook(),
21
+ onRequestEnd,
6
22
  wrapRoot: createSyncHook(),
7
23
  resolveComponent: createSyncHook(),
8
24
  pickContext: createSyncHook(),
@@ -1,5 +1,5 @@
1
1
  import "node:module";
2
- import { createDebugger } from "@modern-js/utils";
2
+ import { createDebugger } from "@modern-js/utils/cli-common";
3
3
  import { assign as lodash_assign } from "@modern-js/utils/lodash";
4
4
  const debug = createDebugger('plugin-server-v2');
5
5
  function initPluginAPI({ context, pluginManager }) {
@@ -4,5 +4,5 @@ import type { CLIPluginExtends } from '../types/cli/plugin.js';
4
4
  import type { PluginManager } from '../types/plugin.js';
5
5
  export declare function initPluginAPI<Extends extends CLIPluginExtends>({ context, pluginManager, }: {
6
6
  context: InternalContext<Extends>;
7
- pluginManager: PluginManager;
7
+ pluginManager: Pick<PluginManager, 'isPluginExists'>;
8
8
  }): CLIPluginAPI<Extends>;
@@ -1,42 +1,33 @@
1
1
  import type { OnAfterBuildFn, OnAfterCreateCompilerFn, OnBeforeBuildFn, OnBeforeCreateCompilerFn, OnDevCompileDoneFn } from '@rsbuild/core';
2
2
  import type { AddCommandFn, AddWatchFilesFn, ConfigFn, InternalRuntimePluginsFn, InternalServerPluginsFn, ModifyBundlerChainFn, ModifyConfigFn, ModifyHtmlPartialsFn, ModifyResolvedConfigFn, ModifyRsbuildConfigFn, ModifyRspackConfigFn, ModifyServerRoutesFn, OnAfterDeployFn, OnAfterDevFn, OnBeforeDeployFn, OnBeforeDevFn, OnBeforeExitFn, OnBeforeRestartFn, OnFileChangedFn, OnPrepareFn, RuntimePluginConfig, ServerPluginConfig } from '../types/cli/hooks.js';
3
+ import type { AsyncHook, CollectAsyncHook } from '../types/hooks.js';
3
4
  import type { DeepPartial } from '../types/utils.js';
4
5
  export type { AddCommandFn, AddWatchFilesFn, ConfigFn, InternalRuntimePluginsFn, InternalServerPluginsFn, ModifyBundlerChainFn, ModifyConfigFn, ModifyHtmlPartialsFn, ModifyResolvedConfigFn, ModifyRsbuildConfigFn, ModifyRspackConfigFn, ModifyServerRoutesFn, OnAfterBuildFn, OnAfterCreateCompilerFn, OnAfterDeployFn, OnAfterDevFn, OnBeforeBuildFn, OnBeforeCreateCompilerFn, OnBeforeDeployFn, OnBeforeDevFn, OnBeforeExitFn, OnBeforeRestartFn, OnDevCompileDoneFn, OnFileChangedFn, OnPrepareFn, RuntimePluginConfig, ServerPluginConfig, };
5
- export declare function initHooks<Config, NormalizedConfig, ExtendBuildUtils, ExtendConfigUtils>(): {
6
- /**
7
- * add config for this cli plugin
8
- */
9
- config: import("../index.js").CollectAsyncHook<ConfigFn<DeepPartial<Config>>>;
10
- /**
11
- * @private
12
- * modify config for this cli plugin
13
- */
14
- modifyConfig: import("../index.js").AsyncHook<ModifyConfigFn<Config, ExtendConfigUtils>>;
15
- /**
16
- * modify final config
17
- */
18
- modifyResolvedConfig: import("../index.js").AsyncHook<ModifyResolvedConfigFn<NormalizedConfig, ExtendConfigUtils>>;
19
- modifyRsbuildConfig: import("../index.js").AsyncHook<ModifyRsbuildConfigFn<ExtendBuildUtils>>;
20
- modifyBundlerChain: import("../index.js").AsyncHook<ModifyBundlerChainFn<ExtendBuildUtils>>;
21
- modifyRspackConfig: import("../index.js").AsyncHook<ModifyRspackConfigFn<ExtendBuildUtils>>;
22
- modifyHtmlPartials: import("../index.js").AsyncHook<ModifyHtmlPartialsFn>;
23
- addCommand: import("../index.js").AsyncHook<AddCommandFn>;
24
- addWatchFiles: import("../index.js").CollectAsyncHook<AddWatchFilesFn>;
25
- onPrepare: import("../index.js").AsyncHook<OnPrepareFn>;
26
- onFileChanged: import("../index.js").AsyncHook<OnFileChangedFn>;
27
- onBeforeRestart: import("../index.js").AsyncHook<OnBeforeRestartFn>;
28
- onBeforeCreateCompiler: import("../index.js").AsyncHook<OnBeforeCreateCompilerFn>;
29
- onAfterCreateCompiler: import("../index.js").AsyncHook<OnAfterCreateCompilerFn>;
30
- onDevCompileDone: import("../index.js").AsyncHook<import("@rsbuild/core").OnAfterDevCompileFn>;
31
- onBeforeBuild: import("../index.js").AsyncHook<OnBeforeBuildFn>;
32
- onAfterBuild: import("../index.js").AsyncHook<OnAfterBuildFn>;
33
- onBeforeDev: import("../index.js").AsyncHook<OnBeforeDevFn>;
34
- onAfterDev: import("../index.js").AsyncHook<OnAfterDevFn>;
35
- onBeforeDeploy: import("../index.js").AsyncHook<OnBeforeDeployFn>;
36
- onAfterDeploy: import("../index.js").AsyncHook<OnAfterDeployFn>;
37
- onBeforeExit: import("../index.js").AsyncHook<OnBeforeExitFn>;
38
- _internalRuntimePlugins: import("../index.js").AsyncHook<InternalRuntimePluginsFn>;
39
- _internalServerPlugins: import("../index.js").AsyncHook<InternalServerPluginsFn>;
40
- modifyServerRoutes: import("../index.js").AsyncHook<ModifyServerRoutesFn>;
6
+ export declare function initHooks<Config, NormalizedConfig, ExtendBuildUtils, ExtendConfigUtils>(): Hooks<Config, NormalizedConfig, ExtendBuildUtils, ExtendConfigUtils>;
7
+ export type Hooks<Config, NormalizedConfig, ExtendBuildUtils, ExtendConfigUtils> = {
8
+ config: CollectAsyncHook<ConfigFn<DeepPartial<Config>>>;
9
+ modifyConfig: AsyncHook<ModifyConfigFn<Config, ExtendConfigUtils>>;
10
+ modifyResolvedConfig: AsyncHook<ModifyResolvedConfigFn<NormalizedConfig, ExtendConfigUtils>>;
11
+ modifyRsbuildConfig: AsyncHook<ModifyRsbuildConfigFn<ExtendBuildUtils>>;
12
+ modifyBundlerChain: AsyncHook<ModifyBundlerChainFn<ExtendBuildUtils>>;
13
+ modifyRspackConfig: AsyncHook<ModifyRspackConfigFn<ExtendBuildUtils>>;
14
+ modifyHtmlPartials: AsyncHook<ModifyHtmlPartialsFn>;
15
+ addCommand: AsyncHook<AddCommandFn>;
16
+ addWatchFiles: CollectAsyncHook<AddWatchFilesFn>;
17
+ onPrepare: AsyncHook<OnPrepareFn>;
18
+ onFileChanged: AsyncHook<OnFileChangedFn>;
19
+ onBeforeRestart: AsyncHook<OnBeforeRestartFn>;
20
+ onBeforeCreateCompiler: AsyncHook<OnBeforeCreateCompilerFn>;
21
+ onAfterCreateCompiler: AsyncHook<OnAfterCreateCompilerFn>;
22
+ onDevCompileDone: AsyncHook<OnDevCompileDoneFn>;
23
+ onBeforeBuild: AsyncHook<OnBeforeBuildFn>;
24
+ onAfterBuild: AsyncHook<OnAfterBuildFn>;
25
+ onBeforeDev: AsyncHook<OnBeforeDevFn>;
26
+ onAfterDev: AsyncHook<OnAfterDevFn>;
27
+ onBeforeDeploy: AsyncHook<OnBeforeDeployFn>;
28
+ onAfterDeploy: AsyncHook<OnAfterDeployFn>;
29
+ onBeforeExit: AsyncHook<OnBeforeExitFn>;
30
+ _internalRuntimePlugins: AsyncHook<InternalRuntimePluginsFn>;
31
+ _internalServerPlugins: AsyncHook<InternalServerPluginsFn>;
32
+ modifyServerRoutes: AsyncHook<ModifyServerRoutesFn>;
41
33
  };
42
- export type Hooks<Config, NormalizedConfig, ExtendBuildUtils, ExtendConfigUtils> = ReturnType<typeof initHooks<Config, NormalizedConfig, ExtendBuildUtils, ExtendConfigUtils>>;
@@ -1,6 +1,12 @@
1
+ export { createAsyncHook, createAsyncInterruptHook, createAsyncPipelineHook, createCollectAsyncHook, createCollectSyncHook, createSyncHook, } from '../hooks.js';
2
+ export type { AppContext, CLIPlugin, CLIPluginAPI, CLIPluginExtends, Entrypoint, InternalContext, } from '../types/cli/index.js';
3
+ export type { AsyncHook, AsyncInterruptHook, AsyncPipelineHook, CollectAsyncHook, CollectSyncHook, PluginHook, PluginHookTap, SyncHook, } from '../types/hooks.js';
4
+ export type { Plugin, PluginManager, TransformFunction, } from '../types/plugin.js';
1
5
  export { initPluginAPI } from './api.js';
2
6
  export { createContext, initAppContext } from './context.js';
3
7
  export { type AddCommandFn, type AddWatchFilesFn, type ConfigFn, type Hooks, type InternalRuntimePluginsFn, type InternalServerPluginsFn, initHooks, type ModifyBundlerChainFn, type ModifyConfigFn, type ModifyHtmlPartialsFn, type ModifyResolvedConfigFn, type ModifyRsbuildConfigFn, type ModifyRspackConfigFn, type ModifyServerRoutesFn, type OnAfterBuildFn, type OnAfterCreateCompilerFn, type OnAfterDeployFn, type OnAfterDevFn, type OnBeforeBuildFn, type OnBeforeCreateCompilerFn, type OnBeforeDeployFn, type OnBeforeDevFn, type OnBeforeExitFn, type OnBeforeRestartFn, type OnDevCompileDoneFn, type OnFileChangedFn, type OnPrepareFn, type RuntimePluginConfig, type ServerPluginConfig, } from './hooks.js';
4
8
  export { cli, createCli, createLoadedConfig, initAppDir } from './run/index.js';
9
+ export type { ConfigEvaluationContext } from './run/config/createLoadedConfig.js';
5
10
  export { createConfigOptions, createStorybookOptions } from './run/create.js';
11
+ export type { CLIOptions, CLIRunOptions, LoadedConfig } from './run/types.js';
6
12
  export { mergeConfig } from './run/utils/mergeConfig.js';
@@ -1,2 +1,6 @@
1
1
  import type { LoadedConfig } from '../types.js';
2
- export declare function createLoadedConfig<T>(appDirectory: string, configFilePath: string | false, otherConfig?: T): Promise<LoadedConfig<T>>;
2
+ export interface ConfigEvaluationContext {
3
+ env: string;
4
+ command: string;
5
+ }
6
+ export declare function createLoadedConfig<T>(appDirectory: string, configFilePath: string | false, otherConfig?: T, context?: ConfigEvaluationContext): Promise<LoadedConfig<T>>;
@@ -1,4 +1,4 @@
1
- import type { InternalContext } from '../../types/cli/context.js';
1
+ import type { AppContext, InternalContext } from '../../types/cli/context.js';
2
2
  import type { CLIPluginExtends } from '../../types/cli/plugin.js';
3
3
  import type { CLIRunOptions } from './types.js';
4
4
  export declare const createCli: <Extends extends CLIPluginExtends>() => {
@@ -6,6 +6,7 @@ export declare const createCli: <Extends extends CLIPluginExtends>() => {
6
6
  appContext: InternalContext<Extends>;
7
7
  }>;
8
8
  run: (options: CLIRunOptions<Extends>) => Promise<void>;
9
+ dispose: () => void;
9
10
  getPrevInitOptions: () => CLIRunOptions<Extends>;
10
11
  };
11
12
  type UselessOptions = 'handleSetupResult' | 'command';
@@ -15,10 +16,10 @@ type CreateConfigOption<Extends extends CLIPluginExtends> = Omit<CLIRunOptions<E
15
16
  };
16
17
  export declare const createConfigOptions: <Extends extends CLIPluginExtends>(options: CreateConfigOption<Extends>) => Promise<{
17
18
  config: Awaited<Extends["normalizedConfig"]> | NonNullable<Awaited<import("../../types/utils.js").UnwrapPromise<Extends["normalizedConfig"]>>>;
18
- getAppContext: () => Readonly<import("../../index.js").AppContext<Extends> & Extends["extendContext"]>;
19
+ getAppContext: () => Readonly<AppContext<Extends> & Extends["extendContext"]>;
19
20
  }>;
20
21
  export declare const createStorybookOptions: <Extends extends CLIPluginExtends>(options: Omit<CreateConfigOption<Extends>, 'command'>) => Promise<{
21
22
  config: Awaited<Extends["normalizedConfig"]> | NonNullable<Awaited<import("../../types/utils.js").UnwrapPromise<Extends["normalizedConfig"]>>>;
22
- getAppContext: () => Readonly<import("../../index.js").AppContext<Extends> & Extends["extendContext"]>;
23
+ getAppContext: () => Readonly<AppContext<Extends> & Extends["extendContext"]>;
23
24
  }>;
24
25
  export {};
@@ -5,9 +5,10 @@ export { run } from './run.js';
5
5
  export { initAppDir } from './utils/initAppDir.js';
6
6
  export { createCli };
7
7
  export declare const cli: {
8
- init: (options: import("./types.js").CLIRunOptions<import("../../index.js").CLIPluginExtends<{}, {}, {}, {}, {}, {}, {}>>) => Promise<{
9
- appContext: import("../../index.js").InternalContext<import("../../index.js").CLIPluginExtends<{}, {}, {}, {}, {}, {}, {}>>;
8
+ init: (options: import("./types.js").CLIRunOptions<import("../index.js").CLIPluginExtends<{}, {}, {}, {}, {}, {}, {}>>) => Promise<{
9
+ appContext: import("../index.js").InternalContext<import("../index.js").CLIPluginExtends<{}, {}, {}, {}, {}, {}, {}>>;
10
10
  }>;
11
- run: (options: import("./types.js").CLIRunOptions<import("../../index.js").CLIPluginExtends<{}, {}, {}, {}, {}, {}, {}>>) => Promise<void>;
12
- getPrevInitOptions: () => import("./types.js").CLIRunOptions<import("../../index.js").CLIPluginExtends<{}, {}, {}, {}, {}, {}, {}>>;
11
+ run: (options: import("./types.js").CLIRunOptions<import("../index.js").CLIPluginExtends<{}, {}, {}, {}, {}, {}, {}>>) => Promise<void>;
12
+ dispose: () => void;
13
+ getPrevInitOptions: () => import("./types.js").CLIRunOptions<import("../index.js").CLIPluginExtends<{}, {}, {}, {}, {}, {}, {}>>;
13
14
  };
@@ -1,8 +1,5 @@
1
- import type { CLIPluginExtends } from '../../types/cli/index.js';
2
- import type { Plugin } from '../../types/plugin.js';
3
- export interface CLIOptions<Extends extends CLIPluginExtends = {
4
- config: {};
5
- }> {
1
+ import type { CLIPlugin, CLIPluginExtends } from '../../types/cli/index.js';
2
+ export interface CLIOptions<Extends extends CLIPluginExtends = CLIPluginExtends> {
6
3
  cwd?: string;
7
4
  version?: string;
8
5
  metaName?: string;
@@ -15,7 +12,7 @@ export interface CLIOptions<Extends extends CLIPluginExtends = {
15
12
  */
16
13
  config?: Extends['config'];
17
14
  configFile: string | false;
18
- internalPlugins?: Plugin[];
15
+ internalPlugins?: CLIPlugin<Extends>[];
19
16
  handleSetupResult?: (params: any, api: Record<string, any>) => Promise<void> | void;
20
17
  }
21
18
  export type LoadedConfig<T> = {
@@ -25,8 +22,6 @@ export type LoadedConfig<T> = {
25
22
  pkgConfig?: T;
26
23
  jsConfig?: T;
27
24
  };
28
- export interface CLIRunOptions<Extends extends CLIPluginExtends = {
29
- config: {};
30
- }> extends CLIOptions<Extends> {
25
+ export interface CLIRunOptions<Extends extends CLIPluginExtends = CLIPluginExtends> extends CLIOptions<Extends> {
31
26
  command: string;
32
27
  }
@@ -1,5 +1,6 @@
1
- import { type Command, program } from '@modern-js/utils';
1
+ import { type Command, program } from '@modern-js/utils/commander';
2
+ import type { CliProgram } from '../../../types/cli/hooks.js';
2
3
  export declare const setProgramVersion: (version?: string) => void;
3
- export declare function initCommandsMap(): void;
4
+ export declare function initCommandsMap(): CliProgram;
4
5
  export type { Command };
5
6
  export { program };
@@ -1,4 +1,5 @@
1
- import type { InternalContext } from '../../../types/index.js';
1
+ import type { FSWatcher } from '@modern-js/utils/watch-options';
2
+ import type { InternalContext } from '../../../types/cli/context.js';
2
3
  import type { CLIPluginExtends } from '../../../types/cli/plugin.js';
3
4
  /**
4
5
  * Editor temp files (e.g. `page.tsx.tmp.<pid>.<hash>`) can be created and
@@ -8,4 +9,4 @@ import type { CLIPluginExtends } from '../../../types/cli/plugin.js';
8
9
  * Treat a vanished file as "nothing to read" instead of rethrowing.
9
10
  */
10
11
  export declare const safeReadFileSync: (filePath: string) => string | undefined;
11
- export declare const createFileWatcher: <Extends extends CLIPluginExtends>(appContext: InternalContext<Extends>) => Promise<import("@modern-js/utils").FSWatcher | undefined>;
12
+ export declare const createFileWatcher: <Extends extends CLIPluginExtends>(appContext: InternalContext<Extends>) => Promise<FSWatcher | undefined>;
@@ -1,2 +1,2 @@
1
- import { createDebugger } from '@modern-js/utils';
1
+ import { createDebugger } from '@modern-js/utils/cli-common';
2
2
  export declare const debug: ReturnType<typeof createDebugger>;
@@ -1,6 +1,6 @@
1
1
  export { createAsyncHook, createAsyncInterruptHook, createAsyncPipelineHook, createCollectAsyncHook, createCollectSyncHook, createSyncHook, } from './hooks.js';
2
2
  export { createPluginManager } from './manager.js';
3
- export type { AppContext, CLIPlugin, CLIPluginAPI, CLIPluginExtends, Entrypoint, InternalContext, RuntimePluginConfig, ServerPluginConfig, } from './types/cli/index.js';
3
+ export type { AppContext, CLIPlugin, CLIPluginAPI, CLIPluginExtends, CliProgram, Entrypoint, InternalContext, RuntimePluginConfig, ServerPluginConfig, } from './types/cli/index.js';
4
4
  export type { AsyncHook, AsyncInterruptHook, AsyncPipelineHook, CollectAsyncHook, CollectSyncHook, PluginHook, PluginHookTap, SyncHook, } from './types/hooks.js';
5
5
  export type { Plugin, PluginManager, TransformFunction, } from './types/plugin.js';
6
6
  export type { InternalRuntimeContext, RuntimeContext, RuntimePlugin, RuntimePluginAPI, RuntimePluginExtends, } from './types/runtime/index.js';
@@ -2,4 +2,4 @@
2
2
  * NOTE: This file will be used in both Node.js and runtime environments. Please avoid importing Node.js-specific APIs.
3
3
  */
4
4
  import type { PluginManager } from './types/plugin.js';
5
- export declare function createPluginManager(): PluginManager;
5
+ export declare function createPluginManager<PluginAPI = {}, Context = {}>(): PluginManager<PluginAPI, Context>;
@@ -1,5 +1,5 @@
1
1
  export type { Hooks, InternalRuntimeContext, RuntimeContext, RuntimePlugin, RuntimePluginAPI, RuntimePluginExtends, } from '../types/runtime/index.js';
2
- export type { Collector, ExtendStreamSSRFn, ResolveComponentFn, RuntimeContextProjection, SSRAssetGroup, SSRAssetTransformInfo, SSRHeadData, SSRHeadPart, SSRHtmlFormatting, SSRRenderAsset, SSRRenderInfo, SSRRenderLifecycle, SSRRenderTerminal, SSRRouterData, SSRTemplateChunk, StreamSSRExtender, StreamSSRInfo, StringSSRCollectorsInfo, TransformRuntimeContextFn, } from '../types/runtime/hooks.js';
2
+ export type { Collector, ExtendStreamSSRFn, OnRenderPreparedFn, OnRequestEndFn, ResolveComponentFn, RuntimeContextProjection, SSRAssetGroup, SSRAssetTransformInfo, SSRHeadData, SSRHeadPart, SSRHtmlFormatting, SSRRenderAsset, SSRRenderInfo, SSRRenderLifecycle, SSRRenderTerminal, SSRRequestEndInfo, SSRRequestPreparedInfo, SSRRequestRouterResult, SSRRequestTerminal, SSRRouterData, SSRTemplateChunk, StreamSSRExtender, StreamSSRInfo, StringSSRCollectorsInfo, TransformRuntimeContextFn, } from '../types/runtime/hooks.js';
3
3
  export { initPluginAPI } from './api.js';
4
4
  export { createRuntimeContext, initRuntimeContext } from './context.js';
5
5
  export { initHooks } from './hooks.js';
@@ -1,4 +1,4 @@
1
- import { createDebugger } from '@modern-js/utils';
1
+ import { createDebugger } from '@modern-js/utils/cli-common';
2
2
  import type { PluginManager } from '../types/plugin.js';
3
3
  import type { ServerPluginAPI } from '../types/server/api.js';
4
4
  import type { InternalServerContext } from '../types/server/context.js';
@@ -1,9 +1,10 @@
1
+ import type { AsyncHook } from '../types/hooks.js';
1
2
  import type { ModifyConfigFn, OnPrepareFn, OnResetFn } from '../types/server/hooks.js';
2
3
  import type { DeepPartial } from '../types/utils.js';
3
4
  export type { ModifyConfigFn, OnPrepareFn, OnResetFn };
4
- export declare function initHooks<Config>(): {
5
- modifyConfig: import("../index.js").AsyncHook<ModifyConfigFn<DeepPartial<Config>>>;
6
- onPrepare: import("../index.js").AsyncHook<OnPrepareFn>;
7
- onReset: import("../index.js").AsyncHook<OnResetFn>;
5
+ export declare function initHooks<Config>(): Hooks<Config>;
6
+ export type Hooks<Config> = {
7
+ modifyConfig: AsyncHook<ModifyConfigFn<DeepPartial<Config>>>;
8
+ onPrepare: AsyncHook<OnPrepareFn>;
9
+ onReset: AsyncHook<OnResetFn>;
8
10
  };
9
- export type Hooks<Config> = ReturnType<typeof initHooks<Config>>;
@@ -1,7 +1,8 @@
1
+ import type { InternalServerContext } from '../../types/server/context.js';
1
2
  import type { ServerPluginExtends } from '../../types/server/plugin.js';
2
3
  import type { ServerRunOptions } from './types.js';
3
4
  export declare const createServer: <Extends extends ServerPluginExtends>() => {
4
- run: (options: ServerRunOptions) => Promise<{
5
- serverContext: import("../../index.js").InternalServerContext<Extends>;
5
+ run(options: ServerRunOptions): Promise<{
6
+ serverContext: InternalServerContext<Extends>;
6
7
  }>;
7
8
  };
@@ -1,8 +1,5 @@
1
+ import type { ServerPluginExtends } from '../../types/server/plugin.js';
1
2
  import { createServer } from './create.js';
2
- export declare const server: {
3
- run: (options: import("./types.js").ServerRunOptions) => Promise<{
4
- serverContext: import("../../index.js").InternalServerContext<import("../../index.js").ServerPluginExtends<{}, {}, {}, {}>>;
5
- }>;
6
- };
3
+ export declare const server: ReturnType<typeof createServer<ServerPluginExtends>>;
7
4
  export type { ServerCreateOptions } from './types.js';
8
5
  export { createServer };
@@ -1,4 +1,4 @@
1
- import type { ServerRoute } from '@modern-js/types';
1
+ import type { ServerRoute } from '@modern-js/types/server';
2
2
  import type { Plugin } from '../../types/plugin.js';
3
3
  /** Registered BFF runtimes. Runtime packages extend this interface. */
4
4
  export interface BffRuntimeRegistry {
@@ -1,5 +1,5 @@
1
1
  import type { BuilderInstance } from '@modern-js/builder';
2
- import type { ServerRoute } from '@modern-js/types';
2
+ import type { ServerRoute } from '@modern-js/types/server';
3
3
  import type { Hooks } from '../../cli/hooks.js';
4
4
  import type { CLIPluginAPI } from './api.js';
5
5
  import type { CLIPlugin, CLIPluginExtends } from './plugin.js';
@@ -1,14 +1,13 @@
1
- import type { ServerPlugin as ServerPluginConfig, ServerRoute } from '@modern-js/types';
1
+ import type { ServerPlugin as ServerPluginConfig } from '@modern-js/types/common';
2
+ import type { ServerRoute } from '@modern-js/types/server';
2
3
  import type { Command } from '@modern-js/utils/commander';
3
4
  import type { ModifyBundlerChainUtils, ModifyRspackConfigUtils, RsbuildConfig, Rspack, RspackChain } from '@rsbuild/core';
4
5
  import type { TransformFunction } from '../plugin.js';
5
6
  import type { MaybePromise } from '../utils.js';
6
7
  import type { Entrypoint } from './context.js';
7
- declare module '@modern-js/utils/commander' {
8
- interface Command {
9
- commandsMap: Map<string, Command>;
10
- }
11
- }
8
+ export type CliProgram = Command & {
9
+ commandsMap: Map<string, Command>;
10
+ };
12
11
  export interface RuntimePluginConfig {
13
12
  name: string;
14
13
  path: string;
@@ -32,7 +31,7 @@ export type ModifyHtmlPartialsFn = (params: {
32
31
  };
33
32
  }) => Promise<void> | void;
34
33
  export type AddCommandFn = (params: {
35
- program: Command;
34
+ program: CliProgram;
36
35
  }) => void;
37
36
  export type OnPrepareFn = () => Promise<void> | void;
38
37
  type WatchFilesReturnType = Array<string> | {
@@ -1,4 +1,4 @@
1
1
  export type { CLIPluginAPI } from './api.js';
2
2
  export type { AppContext, Entrypoint, InternalContext } from './context.js';
3
- export type { RuntimePluginConfig, ServerPluginConfig } from './hooks.js';
3
+ export type { CliProgram, RuntimePluginConfig, ServerPluginConfig, } from './hooks.js';
4
4
  export type { CLIPlugin, CLIPluginExtends } from './plugin.js';
@@ -37,9 +37,9 @@ export type Plugin<PluginAPI = {}, Context = {}> = {
37
37
  */
38
38
  required?: string[];
39
39
  };
40
- export type PluginManager = {
41
- getPlugins: () => Plugin[];
42
- addPlugins: (plugins: Array<Plugin | Falsy>) => void;
40
+ export type PluginManager<PluginAPI = {}, Context = {}> = {
41
+ getPlugins: () => Plugin<PluginAPI, Context>[];
42
+ addPlugins: (plugins: Array<Plugin<PluginAPI, Context> | Falsy>) => void;
43
43
  clear: () => void;
44
44
  isPluginExists: (name: string) => boolean;
45
45
  };
@@ -1,13 +1,15 @@
1
1
  import type { PluginHook, PluginHookTap } from '../hooks.js';
2
2
  import type { DeepPartial } from '../utils.js';
3
3
  import type { RuntimeContext } from './context.js';
4
- import type { ConfigFn, ExtendStreamSSRFn, ExtendStringSSRCollectorsFn, Hooks, OnBeforeRenderFn, PickContextFn, ResolveComponentFn, StringSSRCollectorsInfo, TransformRuntimeContextFn, WrapRootFn } from './hooks.js';
4
+ import type { ConfigFn, ExtendStreamSSRFn, ExtendStringSSRCollectorsFn, Hooks, OnBeforeRenderFn, OnRenderPreparedFn, OnRequestEndFn, PickContextFn, ResolveComponentFn, StringSSRCollectorsInfo, TransformRuntimeContextFn, WrapRootFn } from './hooks.js';
5
5
  import type { RuntimePluginExtends } from './plugin.js';
6
6
  export type RuntimePluginAPI<Extends extends RuntimePluginExtends> = Readonly<{
7
7
  updateRuntimeContext: (updateContext: DeepPartial<RuntimeContext>) => void;
8
8
  getHooks: () => Readonly<Hooks<Extends['config'], RuntimeContext & Extends['extendContext']> & Extends['extendHooks']>;
9
9
  getRuntimeConfig: () => Readonly<Extends['config']>;
10
10
  onBeforeRender: PluginHookTap<OnBeforeRenderFn<Extends['extendContext']>>;
11
+ onRenderPrepared: PluginHookTap<OnRenderPreparedFn<RuntimeContext & Extends['extendContext']>>;
12
+ onRequestEnd: PluginHookTap<OnRequestEndFn<RuntimeContext & Extends['extendContext']>>;
11
13
  wrapRoot: PluginHookTap<WrapRootFn>;
12
14
  resolveComponent: PluginHookTap<ResolveComponentFn>;
13
15
  pickContext: PluginHookTap<PickContextFn<RuntimeContext>>;
@@ -15,6 +15,11 @@ export type SSRRenderInfo<RuntimeContext = object> = {
15
15
  /** Original renderer resource and configuration; interpreted by extensions. */
16
16
  resource?: object;
17
17
  config?: object;
18
+ /** Request-scoped monitors for diagnostics an extension detects mid-render. */
19
+ monitors: {
20
+ error(message: string, ...args: unknown[]): void;
21
+ warn(message: string, ...args: unknown[]): void;
22
+ };
18
23
  };
19
24
  export type SSRHeadPart = {
20
25
  toString(): string;
@@ -86,8 +91,34 @@ export type Collector = SSRRenderLifecycle & {
86
91
  effect: () => void | Promise<void>;
87
92
  };
88
93
  import type React from 'react';
89
- import type { AsyncInterruptHook, CollectSyncHook, SyncHook } from '../hooks.js';
94
+ import type { AsyncHook, AsyncInterruptHook, CollectSyncHook, SyncHook } from '../hooks.js';
90
95
  export type OnBeforeRenderFn<RuntimeContext> = (context: RuntimeContext, interrupt: (info: any) => any) => Promise<any> | any;
96
+ export type SSRRequestRouterResult = {
97
+ statusCode?: number;
98
+ errors?: Record<string, unknown> | null;
99
+ };
100
+ export type SSRRequestPreparedInfo<RuntimeContext = object> = {
101
+ runtimeContext: RuntimeContext;
102
+ /** Native router metadata; extensions may supply another router's result. */
103
+ routerResult?: SSRRequestRouterResult;
104
+ };
105
+ export type OnRenderPreparedFn<RuntimeContext> = (info: SSRRequestPreparedInfo<RuntimeContext>) => SSRRequestPreparedInfo<RuntimeContext> | void | Promise<SSRRequestPreparedInfo<RuntimeContext> | void>;
106
+ export type SSRRequestTerminal = {
107
+ status: 'complete';
108
+ } | {
109
+ status: 'error';
110
+ error: unknown;
111
+ } | {
112
+ status: 'cancelled';
113
+ reason: unknown;
114
+ } | {
115
+ status: 'discarded';
116
+ };
117
+ export type SSRRequestEndInfo<RuntimeContext = object> = {
118
+ runtimeContext: RuntimeContext;
119
+ terminal: SSRRequestTerminal;
120
+ };
121
+ export type OnRequestEndFn<RuntimeContext> = (info: SSRRequestEndInfo<RuntimeContext>) => void | Promise<void>;
91
122
  export type ExtendStringSSRCollectorsFn<RuntimeContext> = (context: RuntimeContext) => Collector;
92
123
  export type StringSSRCollectorsInfo<RuntimeContext = object> = {
93
124
  chunkSet: ChunkSet;
@@ -127,6 +158,10 @@ export type TransformRuntimeContextFn<RuntimeContext> = (projection: RuntimeCont
127
158
  export type ConfigFn<RuntimeConfig> = () => RuntimeConfig;
128
159
  export type Hooks<RuntimeConfig, RuntimeContext> = {
129
160
  onBeforeRender: AsyncInterruptHook<OnBeforeRenderFn<RuntimeContext>>;
161
+ /** Runs after preparation and before native status/error handling. */
162
+ onRenderPrepared: AsyncHook<OnRenderPreparedFn<RuntimeContext>>;
163
+ /** Runs once after response completion, cancellation, discard or failure. */
164
+ onRequestEnd: AsyncHook<OnRequestEndFn<RuntimeContext>>;
130
165
  wrapRoot: SyncHook<WrapRootFn>;
131
166
  resolveComponent: SyncHook<ResolveComponentFn>;
132
167
  pickContext: SyncHook<PickContextFn<RuntimeContext>>;
@@ -1,4 +1,4 @@
1
- import type { ServerRoute } from '@modern-js/types';
1
+ import type { ServerRoute } from '@modern-js/types/server';
2
2
  import type { BffRuntimeFramework } from '../../server/run/types.js';
3
3
  import type { ServerPluginAPI } from './api.js';
4
4
  import type { Hooks } from './hooks.js';
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@bleedingdev/modern-js-plugin",
3
3
  "description": "A Progressive React Framework for modern web development.",
4
- "homepage": "https://github.com/BleedingDev/ultramodern.js#readme",
4
+ "homepage": "https://github.com/ultramodernjs/ultramodern.js#readme",
5
5
  "bugs": {
6
- "url": "https://github.com/BleedingDev/ultramodern.js/issues"
6
+ "url": "https://github.com/ultramodernjs/ultramodern.js/issues"
7
7
  },
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "git+https://github.com/BleedingDev/ultramodern.js.git",
10
+ "url": "git+https://github.com/ultramodernjs/ultramodern.js.git",
11
11
  "directory": "packages/toolkit/plugin"
12
12
  },
13
13
  "license": "MIT",
@@ -17,7 +17,7 @@
17
17
  "modern",
18
18
  "modern.js"
19
19
  ],
20
- "version": "3.9.0-ultramodern.8",
20
+ "version": "3.9.3-ultramodern.1",
21
21
  "types": "./dist/types/index.d.ts",
22
22
  "main": "./dist/cjs/index.js",
23
23
  "exports": {
@@ -62,7 +62,7 @@
62
62
  "typesVersions": {
63
63
  "*": {
64
64
  ".": [
65
- "./dist/index.d.ts"
65
+ "./dist/types/index.d.ts"
66
66
  ],
67
67
  "run": [
68
68
  "./dist/types/cli/run/index.d.ts"
@@ -79,20 +79,19 @@
79
79
  }
80
80
  },
81
81
  "dependencies": {
82
- "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.0-ultramodern.8",
83
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.8",
84
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.8",
85
- "@rsbuild/core": "2.2.3",
82
+ "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.3-ultramodern.1",
83
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.3-ultramodern.1",
84
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.3-ultramodern.1",
85
+ "@rsbuild/core": "2.2.11",
86
86
  "@swc/helpers": "^0.5.23",
87
- "jiti": "^2.7.0"
87
+ "jiti": "2.7.0"
88
88
  },
89
89
  "devDependencies": {
90
- "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.0-ultramodern.8",
91
- "@rslib/core": "1.0.0",
92
- "@types/node": "^26.4.1",
93
- "@types/react": "^19.2.18",
94
- "@typescript/native-preview": "7.0.0-dev.20260707.2",
95
- "typescript": "^7.0.2"
90
+ "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.3-ultramodern.1",
91
+ "@rslib/core": "1.0.3",
92
+ "@types/node": "^26.6.3",
93
+ "@types/react": "^19.3.0",
94
+ "typescript": "7.0.2"
96
95
  },
97
96
  "sideEffects": false,
98
97
  "publishConfig": {
@@ -102,5 +101,8 @@
102
101
  "dev": "rslib build --watch",
103
102
  "build": "rslib build",
104
103
  "test": "rstest"
104
+ },
105
+ "ultramodern": {
106
+ "sourceName": "@modern-js/plugin"
105
107
  }
106
108
  }