rollipop 1.0.0-alpha.24 → 1.0.0-alpha.26

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 (71) hide show
  1. package/dist/common/env.js +2 -2
  2. package/dist/config/defaults.d.ts +10 -4
  3. package/dist/config/defaults.js +8 -3
  4. package/dist/config/index.d.ts +2 -2
  5. package/dist/config/load-config.js +4 -2
  6. package/dist/config/types.d.ts +32 -7
  7. package/dist/constants.d.ts +3 -2
  8. package/dist/constants.js +6 -57
  9. package/dist/core/analyze.js +14 -0
  10. package/dist/core/assets.d.ts +1 -1
  11. package/dist/core/bundler.js +1 -1
  12. package/dist/core/plugins/analyze-plugin.d.ts +11 -0
  13. package/dist/core/plugins/analyze-plugin.js +57 -0
  14. package/dist/core/plugins/index.d.ts +2 -1
  15. package/dist/core/plugins/index.js +2 -0
  16. package/dist/core/rolldown.js +17 -5
  17. package/dist/core/settings.js +2 -2
  18. package/dist/core/types.d.ts +2 -1
  19. package/dist/hmr-runtime.iife.js +51 -35
  20. package/dist/index.d.ts +4 -4
  21. package/dist/node/commands/agent/action.js +1 -1
  22. package/dist/node/commands/start/setup-interactive-mode.js +1 -1
  23. package/dist/package.js +1 -1
  24. package/dist/runtime.js +4 -4
  25. package/dist/server/bundle.js +2 -2
  26. package/dist/server/bundler-pool.d.ts +7 -2
  27. package/dist/server/bundler-pool.js +21 -6
  28. package/dist/server/create-dev-server.js +22 -17
  29. package/dist/server/events/types.d.ts +4 -4
  30. package/dist/server/mcp/context.js +2 -2
  31. package/dist/server/mcp/server.js +1 -1
  32. package/dist/server/mcp/tools/build-info.js +1 -23
  33. package/dist/server/mcp/tools/{device-diagnostics.js → client-diagnostics.js} +19 -19
  34. package/dist/server/mcp/tools/index.js +5 -5
  35. package/dist/server/middlewares/dashboard.js +60 -0
  36. package/dist/server/middlewares/sse.js +2 -0
  37. package/dist/server/middlewares/symbolicate.js +32 -8
  38. package/dist/server/rest/data.js +47 -0
  39. package/dist/server/rest/devtools-targets.js +25 -0
  40. package/dist/server/rest/domains/actions.js +24 -0
  41. package/dist/server/rest/domains/builds.js +37 -0
  42. package/dist/server/rest/domains/bundlers.js +30 -0
  43. package/dist/server/rest/domains/config.js +14 -0
  44. package/dist/server/rest/domains/dev-server.js +14 -0
  45. package/dist/server/rest/domains/devices.js +20 -0
  46. package/dist/server/rest/domains/feature-flags.js +14 -0
  47. package/dist/server/rest/domains/snapshot.js +14 -0
  48. package/dist/server/rest/index.js +56 -0
  49. package/dist/server/rest/response.js +9 -0
  50. package/dist/server/rest/serializers.js +74 -0
  51. package/dist/server/sse/adapter.js +6 -6
  52. package/dist/server/state/store.d.ts +46 -0
  53. package/dist/server/state/store.js +165 -0
  54. package/dist/server/types.d.ts +10 -5
  55. package/dist/storage/file-storage.d.ts +26 -0
  56. package/dist/storage/file-storage.js +49 -0
  57. package/dist/types/hmr.d.ts +1 -26
  58. package/dist/utils/build-options.js +7 -6
  59. package/dist/utils/reset-cache.js +2 -2
  60. package/dist/utils/serialize.js +24 -1
  61. package/dist/utils/transform.js +1 -6
  62. package/package.json +9 -4
  63. package/skills/plugins.md +1 -1
  64. package/src/runtime/hmr-runtime.ts +14 -22
  65. package/src/runtime/react-refresh-utils.ts +75 -5
  66. package/dist/common/constants.js +0 -5
  67. package/dist/common/types.d.ts +0 -10
  68. package/dist/core/fs/data.js +0 -14
  69. package/dist/core/fs/storage.d.ts +0 -15
  70. package/dist/core/fs/storage.js +0 -31
  71. package/dist/utils/runtime-target.js +0 -9
@@ -1,5 +1,5 @@
1
- import "./constants.js";
2
1
  //#region src/common/env.ts
2
+ const DEBUG_KEY = "rollipop";
3
3
  const TRUTHY_VALUES = [
4
4
  "yes",
5
5
  "on",
@@ -27,7 +27,7 @@ function parseDebugKeys() {
27
27
  let debugKeys = null;
28
28
  function isDebugEnabled() {
29
29
  if (debugKeys == null) debugKeys = parseDebugKeys();
30
- return debugKeys["rollipop"] ?? false;
30
+ return debugKeys[DEBUG_KEY] ?? false;
31
31
  }
32
32
  //#endregion
33
33
  export { isDebugEnabled };
@@ -1,5 +1,5 @@
1
1
  import { Reporter } from "../types.js";
2
- import { Config, DevModeConfig, OptimizationConfig, Polyfill, ReactNativeConfig } from "./types.js";
2
+ import { AnalyzerConfig, Config, DevModeConfig, OptimizationConfig, Polyfill, ReactNativeConfig } from "./types.js";
3
3
  import { PluginFlattenConfig } from "./merge-config.js";
4
4
 
5
5
  //#region src/config/defaults.d.ts
@@ -48,12 +48,12 @@ declare function getDefaultConfig(projectRoot: string, mode?: Config['mode']): P
48
48
  };
49
49
  assetRegistryPath: NonNullable<NonNullable<ReactNativeConfig>["assetRegistryPath"]>;
50
50
  hmrClientPath: NonNullable<NonNullable<ReactNativeConfig>["hmrClientPath"]>;
51
- globalIdentifiers: string[];
52
51
  };
53
52
  devMode: {
54
53
  hmr: NonNullable<DevModeConfig["hmr"]>;
55
54
  };
56
55
  reporter: Reporter;
56
+ analyzer: Required<AnalyzerConfig>;
57
57
  terminal: {
58
58
  status: "none" | "compat" | "progress" | undefined;
59
59
  };
@@ -65,7 +65,13 @@ declare function getDefaultConfig(projectRoot: string, mode?: Config['mode']): P
65
65
  nativeTransformPipeline: boolean;
66
66
  };
67
67
  }>;
68
+ interface InternalConfig {
69
+ /**
70
+ * The path to the config file that was used to load the config.
71
+ */
72
+ configFile: string;
73
+ }
68
74
  type DefaultConfig = Awaited<ReturnType<typeof getDefaultConfig>>;
69
- type ResolvedConfig = DefaultConfig & PluginFlattenConfig;
75
+ type ResolvedConfig = DefaultConfig & PluginFlattenConfig & InternalConfig;
70
76
  //#endregion
71
- export { DefaultConfig, ResolvedConfig, getDefaultConfig };
77
+ export { DefaultConfig, InternalConfig, ResolvedConfig, getDefaultConfig };
@@ -1,6 +1,6 @@
1
1
  import { isDebugEnabled } from "../common/env.js";
2
2
  import { stripFlowTypes } from "../common/transformer.js";
3
- import { DEFAULT_ASSET_EXTENSIONS, DEFAULT_ASSET_REGISTRY_PATH, DEFAULT_ENV_FILE, DEFAULT_ENV_PREFIX, DEFAULT_HMR_CLIENT_PATH, DEFAULT_REACT_NATIVE_GLOBAL_IDENTIFIERS, DEFAULT_RESOLVER_ALIAS_FIELDS, DEFAULT_RESOLVER_CONDITION_NAMES, DEFAULT_RESOLVER_MAIN_FIELDS, DEFAULT_RUNTIME_TARGET, DEFAULT_SOURCE_EXTENSIONS } from "../constants.js";
3
+ import { DEFAULT_ANALYZE_FILE, DEFAULT_ANALYZE_REPORT_FILE, DEFAULT_ASSET_EXTENSIONS, DEFAULT_ASSET_REGISTRY_PATH, DEFAULT_ENV_FILE, DEFAULT_ENV_PREFIX, DEFAULT_HMR_CLIENT_PATH, DEFAULT_RESOLVER_ALIAS_FIELDS, DEFAULT_RESOLVER_CONDITION_NAMES, DEFAULT_RESOLVER_MAIN_FIELDS, DEFAULT_RUNTIME_TARGET, DEFAULT_SOURCE_EXTENSIONS } from "../constants.js";
4
4
  import { getInitializeCorePath, getPolyfillScriptPaths } from "../internal/react-native.js";
5
5
  import { resolvePackagePath } from "../utils/node-resolve.js";
6
6
  import { ClientLogReporter } from "../utils/reporters.js";
@@ -53,11 +53,16 @@ async function getDefaultConfig(projectRoot, mode) {
53
53
  */
54
54
  filter: { code: /\bcodegenNativeComponent</ } },
55
55
  assetRegistryPath: DEFAULT_ASSET_REGISTRY_PATH,
56
- hmrClientPath: DEFAULT_HMR_CLIENT_PATH,
57
- globalIdentifiers: DEFAULT_REACT_NATIVE_GLOBAL_IDENTIFIERS
56
+ hmrClientPath: DEFAULT_HMR_CLIENT_PATH
58
57
  },
59
58
  devMode: { hmr: true },
60
59
  reporter: new ClientLogReporter(),
60
+ analyzer: {
61
+ enabled: false,
62
+ analyzeFile: DEFAULT_ANALYZE_FILE,
63
+ reportFile: DEFAULT_ANALYZE_REPORT_FILE,
64
+ autoOpen: false
65
+ },
61
66
  terminal: { status: (() => {
62
67
  if (isDebugEnabled()) return "compat";
63
68
  if (process.stderr.isTTY) return "progress";
@@ -1,5 +1,5 @@
1
- import { BabelTransformConfig, CodegenConfig, Config, DevModeConfig, ExperimentalConfig, FlowConfig, HmrConfig, OptimizationConfig, PluginOption, Polyfill, PolyfillOptions, PolyfillType, PolyfillWithCode, PolyfillWithPath, ReactNativeConfig, ResolverConfig, RolldownConfig, RollipopReactNativeFlowConfig, RollipopReactNativeWorkletsConfig, SerializerConfig, SwcTransformConfig, TerminalConfig, TransformRule, TransformerConfig, WatcherConfig } from "./types.js";
1
+ import { AnalyzerConfig, BabelTransformConfig, CodegenConfig, Config, DevModeConfig, ExperimentalConfig, FlowConfig, HmrConfig, OptimizationConfig, PluginOption, Polyfill, PolyfillOptions, PolyfillType, PolyfillWithCode, PolyfillWithPath, ReactNativeConfig, ResolverConfig, RolldownConfig, RollipopReactNativeFlowConfig, RollipopReactNativeWorkletsConfig, SerializerConfig, SwcTransformConfig, TerminalConfig, TransformRule, TransformerConfig, WatcherConfig } from "./types.js";
2
2
  import { PluginFlattenConfig, mergeConfig } from "./merge-config.js";
3
- import { DefaultConfig, ResolvedConfig, getDefaultConfig } from "./defaults.js";
3
+ import { DefaultConfig, InternalConfig, ResolvedConfig, getDefaultConfig } from "./defaults.js";
4
4
  import { DefineConfigContext, DynamicUserConfig, UserConfig, defineConfig } from "./define-config.js";
5
5
  import { LoadConfigOptions, flattenPluginOption, invokeConfigResolved, loadConfig, resolvePluginConfig } from "./load-config.js";
@@ -2,7 +2,7 @@ import { getDefaultConfig } from "./defaults.js";
2
2
  import { createPluginContext } from "../core/plugins/context.js";
3
3
  import { mergeConfig } from "./merge-config.js";
4
4
  import path from "node:path";
5
- import { omit } from "es-toolkit";
5
+ import { invariant, omit } from "es-toolkit";
6
6
  import * as c12 from "c12";
7
7
  //#region src/config/load-config.ts
8
8
  const CONFIG_FILE_NAME = "rollipop";
@@ -17,7 +17,7 @@ async function loadConfig(options = {}) {
17
17
  },
18
18
  rcFile: false
19
19
  };
20
- const { config: userConfig } = await c12.loadConfig(configFile ? {
20
+ const { config: userConfig, configFile: resolvedConfigFile } = await c12.loadConfig(configFile ? {
21
21
  configFile: path.resolve(cwd, configFile),
22
22
  configFileRequired: true
23
23
  } : {
@@ -26,12 +26,14 @@ async function loadConfig(options = {}) {
26
26
  name: CONFIG_FILE_NAME,
27
27
  ...commonOptions
28
28
  });
29
+ invariant(resolvedConfigFile != null, "Failed to get resolved config file");
29
30
  const plugins = await flattenPluginOption(userConfig.plugins);
30
31
  const resolvedConfig = {
31
32
  ...await resolvePluginConfig(mergeConfig(defaultConfig, {
32
33
  ...userConfig,
33
34
  plugins
34
35
  }), plugins),
36
+ configFile: resolvedConfigFile,
35
37
  plugins
36
38
  };
37
39
  if (!path.isAbsolute(resolvedConfig.entry)) resolvedConfig.entry = path.resolve(resolvedConfig.root, resolvedConfig.entry);
@@ -57,6 +57,10 @@ interface Config {
57
57
  * Reporter configuration.
58
58
  */
59
59
  reporter?: Reporter;
60
+ /**
61
+ * Bundle analyzer configuration.
62
+ */
63
+ analyzer?: AnalyzerConfig;
60
64
  /**
61
65
  * Dev mode specific configuration. (for dev server)
62
66
  */
@@ -422,12 +426,6 @@ interface ReactNativeConfig {
422
426
  * Defaults to: `react-native/Libraries/Utilities/HMRClient.js`
423
427
  */
424
428
  hmrClientPath?: string | ((root: string) => MaybePromise<string>);
425
- /**
426
- * Reserved global identifiers of React Native.
427
- *
428
- * Defaults to: Global identifier list of React Native 0.83
429
- */
430
- globalIdentifiers?: string[];
431
429
  }
432
430
  interface CodegenConfig {
433
431
  /**
@@ -435,6 +433,33 @@ interface CodegenConfig {
435
433
  */
436
434
  filter?: rolldown.HookFilter | TopLevelFilterExpression[];
437
435
  }
436
+ interface AnalyzerConfig {
437
+ /**
438
+ * Whether to enable the bundle analyzer.
439
+ *
440
+ * Defaults to: `false`
441
+ */
442
+ enabled?: boolean;
443
+ /**
444
+ * Output filename for the analysis data.
445
+ *
446
+ * Defaults to: `analyze-data.json`
447
+ */
448
+ analyzeFile?: string;
449
+ /**
450
+ * Output filename for the generated HTML report.
451
+ *
452
+ * Defaults to: `report.html`
453
+ */
454
+ reportFile?: string;
455
+ /**
456
+ * Automatically open the generated report in the browser.
457
+ * (Only available in `build` mode)
458
+ *
459
+ * Defaults to: `false`
460
+ */
461
+ autoOpen?: boolean;
462
+ }
438
463
  interface TerminalConfig {
439
464
  /**
440
465
  * Status of the terminal.
@@ -452,4 +477,4 @@ interface RolldownConfig {
452
477
  output?: rolldown.OutputOptions;
453
478
  }
454
479
  //#endregion
455
- export { BabelTransformConfig, CodegenConfig, Config, DevModeConfig, ExperimentalConfig, FlowConfig, HmrConfig, OptimizationConfig, PluginOption, Polyfill, PolyfillOptions, PolyfillType, PolyfillWithCode, PolyfillWithPath, ReactNativeConfig, ResolverConfig, RolldownConfig, type RollipopReactNativeFlowConfig, type RollipopReactNativeWorkletsConfig, SerializerConfig, SwcTransformConfig, TerminalConfig, TransformRule, TransformerConfig, WatcherConfig };
480
+ export { AnalyzerConfig, BabelTransformConfig, CodegenConfig, Config, DevModeConfig, ExperimentalConfig, FlowConfig, HmrConfig, OptimizationConfig, PluginOption, Polyfill, PolyfillOptions, PolyfillType, PolyfillWithCode, PolyfillWithPath, ReactNativeConfig, ResolverConfig, RolldownConfig, type RollipopReactNativeFlowConfig, type RollipopReactNativeWorkletsConfig, SerializerConfig, SwcTransformConfig, TerminalConfig, TransformRule, TransformerConfig, WatcherConfig };
@@ -1,5 +1,5 @@
1
1
  declare namespace constants_d_exports {
2
- export { DEFAULT_ASSET_EXTENSIONS, DEFAULT_ASSET_REGISTRY_PATH, DEFAULT_ENV_FILE, DEFAULT_ENV_PREFIX, DEFAULT_HMR_CLIENT_PATH, DEFAULT_IMAGE_EXTENSIONS, DEFAULT_REACT_NATIVE_GLOBAL_IDENTIFIERS, DEFAULT_RESOLVER_ALIAS_FIELDS, DEFAULT_RESOLVER_CONDITION_NAMES, DEFAULT_RESOLVER_MAIN_FIELDS, DEFAULT_RUNTIME_TARGET, DEFAULT_SOURCE_EXTENSIONS, IMAGE_EXTENSIONS, ROLLIPOP_VERSION, ROLLIPOP_VIRTUAL_ENTRY_ID, ROLLIPOP_VIRTUAL_PREFIX };
2
+ export { DEFAULT_ANALYZE_FILE, DEFAULT_ANALYZE_REPORT_FILE, DEFAULT_ASSET_EXTENSIONS, DEFAULT_ASSET_REGISTRY_PATH, DEFAULT_ENV_FILE, DEFAULT_ENV_PREFIX, DEFAULT_HMR_CLIENT_PATH, DEFAULT_IMAGE_EXTENSIONS, DEFAULT_RESOLVER_ALIAS_FIELDS, DEFAULT_RESOLVER_CONDITION_NAMES, DEFAULT_RESOLVER_MAIN_FIELDS, DEFAULT_RUNTIME_TARGET, DEFAULT_SOURCE_EXTENSIONS, IMAGE_EXTENSIONS, ROLLIPOP_VERSION, ROLLIPOP_VIRTUAL_ENTRY_ID, ROLLIPOP_VIRTUAL_PREFIX };
3
3
  }
4
4
  /**
5
5
  * @see `vite.config.ts`
@@ -28,9 +28,10 @@ declare const IMAGE_EXTENSIONS: string[];
28
28
  declare const DEFAULT_ASSET_EXTENSIONS: string[];
29
29
  declare const DEFAULT_ASSET_REGISTRY_PATH = "react-native/Libraries/Image/AssetRegistry.js";
30
30
  declare const DEFAULT_HMR_CLIENT_PATH = "react-native/Libraries/Utilities/HMRClient.js";
31
- declare const DEFAULT_REACT_NATIVE_GLOBAL_IDENTIFIERS: string[];
32
31
  declare const DEFAULT_ENV_PREFIX = "ROLLIPOP_";
33
32
  declare const DEFAULT_ENV_FILE = ".env";
34
33
  declare const DEFAULT_RUNTIME_TARGET = "hermes-v1";
34
+ declare const DEFAULT_ANALYZE_FILE = "analyze-data.json";
35
+ declare const DEFAULT_ANALYZE_REPORT_FILE = "report.html";
35
36
  //#endregion
36
37
  export { constants_d_exports };
package/dist/constants.js CHANGED
@@ -1,13 +1,14 @@
1
1
  import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
2
  //#region src/constants.ts
3
3
  var constants_exports = /* @__PURE__ */ __exportAll({
4
+ DEFAULT_ANALYZE_FILE: () => DEFAULT_ANALYZE_FILE,
5
+ DEFAULT_ANALYZE_REPORT_FILE: () => DEFAULT_ANALYZE_REPORT_FILE,
4
6
  DEFAULT_ASSET_EXTENSIONS: () => DEFAULT_ASSET_EXTENSIONS,
5
7
  DEFAULT_ASSET_REGISTRY_PATH: () => DEFAULT_ASSET_REGISTRY_PATH,
6
8
  DEFAULT_ENV_FILE: () => DEFAULT_ENV_FILE,
7
9
  DEFAULT_ENV_PREFIX: () => DEFAULT_ENV_PREFIX,
8
10
  DEFAULT_HMR_CLIENT_PATH: () => DEFAULT_HMR_CLIENT_PATH,
9
11
  DEFAULT_IMAGE_EXTENSIONS: () => DEFAULT_IMAGE_EXTENSIONS,
10
- DEFAULT_REACT_NATIVE_GLOBAL_IDENTIFIERS: () => DEFAULT_REACT_NATIVE_GLOBAL_IDENTIFIERS,
11
12
  DEFAULT_RESOLVER_ALIAS_FIELDS: () => DEFAULT_RESOLVER_ALIAS_FIELDS,
12
13
  DEFAULT_RESOLVER_CONDITION_NAMES: () => DEFAULT_RESOLVER_CONDITION_NAMES,
13
14
  DEFAULT_RESOLVER_MAIN_FIELDS: () => DEFAULT_RESOLVER_MAIN_FIELDS,
@@ -18,7 +19,7 @@ var constants_exports = /* @__PURE__ */ __exportAll({
18
19
  ROLLIPOP_VIRTUAL_ENTRY_ID: () => ROLLIPOP_VIRTUAL_ENTRY_ID,
19
20
  ROLLIPOP_VIRTUAL_PREFIX: () => ROLLIPOP_VIRTUAL_PREFIX
20
21
  });
21
- const ROLLIPOP_VERSION = "1.0.0-alpha.24";
22
+ const ROLLIPOP_VERSION = "1.0.0-alpha.26";
22
23
  const ROLLIPOP_VIRTUAL_PREFIX = "\0rollipop/";
23
24
  const ROLLIPOP_VIRTUAL_ENTRY_ID = `${ROLLIPOP_VIRTUAL_PREFIX}entry`;
24
25
  /**
@@ -86,62 +87,10 @@ const DEFAULT_ASSET_EXTENSIONS = [
86
87
  ];
87
88
  const DEFAULT_ASSET_REGISTRY_PATH = "react-native/Libraries/Image/AssetRegistry.js";
88
89
  const DEFAULT_HMR_CLIENT_PATH = "react-native/Libraries/Utilities/HMRClient.js";
89
- const DEFAULT_REACT_NATIVE_GLOBAL_IDENTIFIERS = [
90
- "Promise",
91
- "regeneratorRuntime",
92
- "XMLHttpRequest",
93
- "FormData",
94
- "fetch",
95
- "Headers",
96
- "Request",
97
- "Response",
98
- "WebSocket",
99
- "Blob",
100
- "File",
101
- "FileReader",
102
- "URL",
103
- "URLSearchParams",
104
- "AbortController",
105
- "AbortSignal",
106
- "queueMicrotask",
107
- "setImmediate",
108
- "clearImmediate",
109
- "requestIdleCallback",
110
- "cancelIdleCallback",
111
- "setTimeout",
112
- "clearTimeout",
113
- "setInterval",
114
- "clearInterval",
115
- "requestAnimationFrame",
116
- "cancelAnimationFrame",
117
- "DOMRect",
118
- "DOMRectReadOnly",
119
- "DOMRectList",
120
- "HTMLCollection",
121
- "NodeList",
122
- "Node",
123
- "Document",
124
- "CharacterData",
125
- "Text",
126
- "Element",
127
- "HTMLElement",
128
- "IntersectionObserver",
129
- "MutationObserver",
130
- "MutationRecord",
131
- "EventCounts",
132
- "Performance",
133
- "PerformanceEntry",
134
- "PerformanceEventTiming",
135
- "PerformanceLongTaskTiming",
136
- "PerformanceMark",
137
- "PerformanceMeasure",
138
- "PerformanceObserver",
139
- "PerformanceObserverEntryList",
140
- "PerformanceResourceTiming",
141
- "TaskAttributionTiming"
142
- ];
143
90
  const DEFAULT_ENV_PREFIX = "ROLLIPOP_";
144
91
  const DEFAULT_ENV_FILE = ".env";
145
92
  const DEFAULT_RUNTIME_TARGET = "hermes-v1";
93
+ const DEFAULT_ANALYZE_FILE = "analyze-data.json";
94
+ const DEFAULT_ANALYZE_REPORT_FILE = "report.html";
146
95
  //#endregion
147
- export { DEFAULT_ASSET_EXTENSIONS, DEFAULT_ASSET_REGISTRY_PATH, DEFAULT_ENV_FILE, DEFAULT_ENV_PREFIX, DEFAULT_HMR_CLIENT_PATH, DEFAULT_REACT_NATIVE_GLOBAL_IDENTIFIERS, DEFAULT_RESOLVER_ALIAS_FIELDS, DEFAULT_RESOLVER_CONDITION_NAMES, DEFAULT_RESOLVER_MAIN_FIELDS, DEFAULT_RUNTIME_TARGET, DEFAULT_SOURCE_EXTENSIONS, IMAGE_EXTENSIONS, ROLLIPOP_VERSION, ROLLIPOP_VIRTUAL_ENTRY_ID, ROLLIPOP_VIRTUAL_PREFIX, constants_exports };
96
+ export { DEFAULT_ANALYZE_FILE, DEFAULT_ANALYZE_REPORT_FILE, DEFAULT_ASSET_EXTENSIONS, DEFAULT_ASSET_REGISTRY_PATH, DEFAULT_ENV_FILE, DEFAULT_ENV_PREFIX, DEFAULT_HMR_CLIENT_PATH, DEFAULT_RESOLVER_ALIAS_FIELDS, DEFAULT_RESOLVER_CONDITION_NAMES, DEFAULT_RESOLVER_MAIN_FIELDS, DEFAULT_RUNTIME_TARGET, DEFAULT_SOURCE_EXTENSIONS, IMAGE_EXTENSIONS, ROLLIPOP_VERSION, ROLLIPOP_VIRTUAL_ENTRY_ID, ROLLIPOP_VIRTUAL_PREFIX, constants_exports };
@@ -0,0 +1,14 @@
1
+ import { FileStorage } from "../storage/file-storage.js";
2
+ import path from "node:path";
3
+ //#region src/core/analyze.ts
4
+ function getAnalyzeDirectory(projectRoot) {
5
+ return path.join(FileStorage.getPath(projectRoot), "analyze");
6
+ }
7
+ function getAnalyzeDataPath(projectRoot, bundlerId) {
8
+ return path.join(getAnalyzeDirectory(projectRoot), `${bundlerId}.json`);
9
+ }
10
+ function getAnalyzeReportPath(projectRoot, bundlerId) {
11
+ return path.join(getAnalyzeDirectory(projectRoot), `${bundlerId}.html`);
12
+ }
13
+ //#endregion
14
+ export { getAnalyzeDataPath, getAnalyzeReportPath };
@@ -52,7 +52,7 @@ interface ResolveScaledAssetsOptions {
52
52
  declare function resolveScaledAssets(options: ResolveScaledAssetsOptions): Promise<AssetData>;
53
53
  declare function platformSuffixPattern(context: AssetContext): string;
54
54
  declare function stripSuffix(assetPath: string, context: AssetContext): string;
55
- declare function getAssetPriority(assetPath: string, context: AssetContext): 0 | 3 | 2 | 1;
55
+ declare function getAssetPriority(assetPath: string, context: AssetContext): 3 | 2 | 1 | 0;
56
56
  interface GetSuffixedPathOptions {
57
57
  scale?: AssetScale;
58
58
  platform?: string;
@@ -1,7 +1,7 @@
1
+ import { FileStorage } from "../storage/file-storage.js";
1
2
  import { Logo } from "../common/logo.js";
2
3
  import { resolveBuildOptions } from "../utils/build-options.js";
3
4
  import { createId } from "../utils/id.js";
4
- import { FileStorage } from "./fs/storage.js";
5
5
  import { getOverrideOptions, getOverrideOptionsForDevServer, resolveRolldownOptions } from "./rolldown.js";
6
6
  import fs from "node:fs";
7
7
  import path from "node:path";
@@ -0,0 +1,11 @@
1
+ import { BundlerContext } from "../types.js";
2
+ import { AnalyzerConfig } from "../../config/types.js";
3
+ import * as rolldown from "@rollipop/rolldown";
4
+
5
+ //#region src/core/plugins/analyze-plugin.d.ts
6
+ interface AnalyzePluginOptions extends Required<AnalyzerConfig> {
7
+ context: BundlerContext;
8
+ }
9
+ declare function analyzePlugin(options: AnalyzePluginOptions): rolldown.Plugin[] | null;
10
+ //#endregion
11
+ export { AnalyzePluginOptions, analyzePlugin };
@@ -0,0 +1,57 @@
1
+ import { getAnalyzeDataPath, getAnalyzeReportPath } from "../analyze.js";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import * as rolldownExperimental from "@rollipop/rolldown/experimental";
5
+ import open from "open";
6
+ import { generateReport } from "rolldown-analyzer/node";
7
+ //#region src/core/plugins/analyze-plugin.ts
8
+ function analyzePlugin(options) {
9
+ if (!options.enabled) return null;
10
+ const { analyzeFile, reportFile, autoOpen, context } = options;
11
+ return [rolldownExperimental.bundleAnalyzerPlugin({ fileName: analyzeFile }), {
12
+ name: "rollipop:analyze",
13
+ async generateBundle(outputOptions, output) {
14
+ const targetAsset = output[analyzeFile];
15
+ if (targetAsset?.type !== "asset") {
16
+ this.debug(`Analyzer plugin: No asset found for ${analyzeFile}`);
17
+ return;
18
+ }
19
+ const outDir = getOutDir(outputOptions);
20
+ let analyzeFilePath;
21
+ let reportFilePath;
22
+ if (outDir == null || context.buildType === "serve") {
23
+ analyzeFilePath = getAnalyzeDataPath(context.root, context.id);
24
+ reportFilePath = getAnalyzeReportPath(context.root, context.id);
25
+ } else {
26
+ analyzeFilePath = path.resolve(outDir, analyzeFile);
27
+ reportFilePath = path.resolve(outDir, reportFile);
28
+ }
29
+ fs.mkdirSync(path.dirname(analyzeFilePath), { recursive: true });
30
+ fs.mkdirSync(path.dirname(reportFilePath), { recursive: true });
31
+ fs.writeFileSync(analyzeFilePath, targetAsset.source);
32
+ await generateReport({
33
+ preset: "lite",
34
+ dataPath: analyzeFilePath,
35
+ filename: reportFilePath
36
+ });
37
+ if (context.buildType === "build") {
38
+ this.info(`Analysis data generated at '${analyzeFilePath}'`);
39
+ this.info(`Analysis report generated at '${reportFilePath}'`);
40
+ if (autoOpen) {
41
+ this.info(`Opening analysis report in your browser...`);
42
+ open(reportFilePath).catch((error) => {
43
+ this.warn("Failed to open analysis report automatically");
44
+ this.debug(error instanceof Error ? error.message : String(error));
45
+ });
46
+ }
47
+ }
48
+ }
49
+ }];
50
+ }
51
+ function getOutDir(options) {
52
+ if (options.dir) return options.dir;
53
+ if (options.file) return path.dirname(options.file);
54
+ return null;
55
+ }
56
+ //#endregion
57
+ export { analyzePlugin };
@@ -4,10 +4,11 @@ import { BabelPluginOptions, babelPlugin } from "./babel-plugin.js";
4
4
  import { SwcPluginOptions, swcPlugin } from "./swc-plugin.js";
5
5
  import { ReporterPluginOptions, reporterPlugin } from "./reporter-plugin.js";
6
6
  import { DevServerPluginOptions, devServerPlugin } from "./dev-server-plugin.js";
7
+ import { AnalyzePluginOptions, analyzePlugin } from "./analyze-plugin.js";
7
8
 
8
9
  //#region src/core/plugins/index.d.ts
9
10
  declare namespace index_d_exports {
10
- export { BabelPluginOptions, DevServerPluginOptions, EntryPluginOptions, ReactNativePluginOptions, ReporterPluginOptions, SwcPluginOptions, babelPlugin as babel, devServerPlugin as devServer, entryPlugin as entry, reactNativePlugin as reactNative, reporterPlugin as reporter, swcPlugin as swc };
11
+ export { AnalyzePluginOptions, BabelPluginOptions, DevServerPluginOptions, EntryPluginOptions, ReactNativePluginOptions, ReporterPluginOptions, SwcPluginOptions, analyzePlugin as analyze, babelPlugin as babel, devServerPlugin as devServer, entryPlugin as entry, reactNativePlugin as reactNative, reporterPlugin as reporter, swcPlugin as swc };
11
12
  }
12
13
  //#endregion
13
14
  export { index_d_exports };
@@ -5,8 +5,10 @@ import { babelPlugin } from "./babel-plugin.js";
5
5
  import { swcPlugin } from "./swc-plugin.js";
6
6
  import { reporterPlugin } from "./reporter-plugin.js";
7
7
  import { devServerPlugin } from "./dev-server-plugin.js";
8
+ import { analyzePlugin } from "./analyze-plugin.js";
8
9
  //#region src/core/plugins/index.ts
9
10
  var plugins_exports = /* @__PURE__ */ __exportAll({
11
+ analyze: () => analyzePlugin,
10
12
  babel: () => babelPlugin,
11
13
  devServer: () => devServerPlugin,
12
14
  entry: () => entryPlugin,
@@ -9,7 +9,6 @@ import { applyOverrideRolldownOptions } from "../config/compose-override.js";
9
9
  import { createVirtualModuleId, escapeVirtualModuleId } from "../utils/id.js";
10
10
  import { resolveHmrConfig } from "../utils/config.js";
11
11
  import { defineEnvFromObject } from "../utils/env.js";
12
- import { resolveRuntimeTarget } from "../utils/runtime-target.js";
13
12
  import { getBaseUrl } from "../utils/server.js";
14
13
  import { getBuildTotalModules, setBuildTotalModules } from "../utils/storage.js";
15
14
  import { transformWithRollipop } from "../utils/transform.js";
@@ -21,6 +20,7 @@ import { babelPlugin } from "./plugins/babel-plugin.js";
21
20
  import { swcPlugin } from "./plugins/swc-plugin.js";
22
21
  import { reporterPlugin } from "./plugins/reporter-plugin.js";
23
22
  import { devServerPlugin } from "./plugins/dev-server-plugin.js";
23
+ import { analyzePlugin } from "./plugins/analyze-plugin.js";
24
24
  import "./plugins/index.js";
25
25
  import fs from "node:fs";
26
26
  import path from "node:path";
@@ -43,7 +43,6 @@ async function resolveRolldownOptions(context, config, buildOptions, devEngineOp
43
43
  const { banner: rolldownBanner, footer: rolldownFooter, postBanner: rolldownPostBanner, postFooter: rolldownPostFooter, intro: rolldownIntro, outro: rolldownOutro, shimMissingExports: rolldownShimMissingExports } = config.serializer;
44
44
  const { flow: _flow, babel: _babel, swc: _swc, ...rolldownTransform } = config.transformer;
45
45
  const { treeshake: rolldownTreeshake, minify: rolldownMinify, lazyBarrel: rolldownLazyBarrel, ...rolldownOptimization } = config.optimization;
46
- const { globalIdentifiers: rolldownGlobalIdentifiers } = config.reactNative;
47
46
  const { sourcemap: rolldownSourcemap, sourcemapBaseUrl: rolldownSourcemapBaseUrl, sourcemapDebugIds: rolldownSourcemapDebugIds, sourcemapIgnoreList: rolldownSourcemapIgnoreList, sourcemapPathTransform: rolldownSourcemapPathTransform } = config;
48
47
  const userPlugins = config.plugins;
49
48
  const mergedResolveOptions = merge({ extensions: getResolveExtensions({
@@ -75,6 +74,7 @@ async function resolveRolldownOptions(context, config, buildOptions, devEngineOp
75
74
  const swcPluginOptions = resolveSwcPluginOptions(config, context);
76
75
  const devServerPluginOptions = resolveDevServerPluginOptions(config, hmrConfig);
77
76
  const reporterPluginOptions = resolveReporterPluginOptions(config, context, buildOptions);
77
+ const analyzePluginOptions = resolveAnalyzePluginOptions(config, context);
78
78
  const finalOptions = await applyDangerouslyOverrideOptionsFinalizer(config, {
79
79
  platform: "neutral",
80
80
  cwd: config.root,
@@ -97,6 +97,7 @@ async function resolveRolldownOptions(context, config, buildOptions, devEngineOp
97
97
  swcPlugin(swcPluginOptions),
98
98
  devServerPlugin(devServerPluginOptions),
99
99
  reporterPlugin(reporterPluginOptions),
100
+ analyzePlugin(analyzePluginOptions),
100
101
  userPlugins
101
102
  ]),
102
103
  checks: {
@@ -145,7 +146,6 @@ async function resolveRolldownOptions(context, config, buildOptions, devEngineOp
145
146
  sourcemapIgnoreList: rolldownSourcemapIgnoreList,
146
147
  sourcemapPathTransform: rolldownSourcemapPathTransform ?? createProjectRootSourcemapPathTransform(config.root),
147
148
  codeSplitting: false,
148
- globalIdentifiers: rolldownGlobalIdentifiers,
149
149
  persistentCache: cache
150
150
  });
151
151
  resolveRolldownOptions.cache.set(context.id, finalOptions);
@@ -182,7 +182,7 @@ function resolveReactNativeBuiltinPluginConfig(config) {
182
182
  if (!config.experimental?.nativeTransformPipeline) return null;
183
183
  return {
184
184
  envName: config.mode,
185
- runtimeTarget: resolveRuntimeTarget(config.runtimeTarget),
185
+ runtimeTarget: config.runtimeTarget,
186
186
  flow: config.experimental.flow,
187
187
  worklets: resolveWorkletsConfig(config)
188
188
  };
@@ -229,6 +229,15 @@ function resolveReporterPluginOptions(config, context, buildOptions) {
229
229
  ].filter(isNotNil))
230
230
  };
231
231
  }
232
+ function resolveAnalyzePluginOptions(config, context) {
233
+ return {
234
+ context,
235
+ enabled: config.analyzer.enabled,
236
+ analyzeFile: config.analyzer.analyzeFile,
237
+ reportFile: config.analyzer.reportFile,
238
+ autoOpen: config.analyzer.autoOpen
239
+ };
240
+ }
232
241
  function createBuildTotalModulesReporter(context) {
233
242
  return { update(event) {
234
243
  if (event.type === "bundle_build_done") setBuildTotalModules(context.storage, context.id, event.totalModules);
@@ -333,7 +342,10 @@ function getOverrideOptionsForDevServer(buildOptions) {
333
342
  /**
334
343
  * @see `rollipopReactRefreshWrapperPlugin`
335
344
  */
336
- refresh: false
345
+ refresh: {
346
+ refreshReg: "$RefreshReg$",
347
+ refreshSig: "$RefreshSig$"
348
+ }
337
349
  } },
338
350
  experimental: { incrementalBuild: true },
339
351
  treeshake: false
@@ -1,10 +1,10 @@
1
- import { getSharedDataPath } from "./fs/data.js";
1
+ import { FileStorage } from "../storage/file-storage.js";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import { merge } from "es-toolkit";
5
5
  //#region src/core/settings.ts
6
6
  function getSettingsPath(basePath) {
7
- return path.join(getSharedDataPath(basePath), "settings.json");
7
+ return path.join(FileStorage.getPath(basePath), "settings.json");
8
8
  }
9
9
  function loadSettings(basePath) {
10
10
  const settingsPath = getSettingsPath(basePath);
@@ -1,4 +1,4 @@
1
- import { FileStorage } from "./fs/storage.js";
1
+ import { FileStorage } from "../storage/file-storage.js";
2
2
  import * as rolldown from "@rollipop/rolldown";
3
3
  import { DevEngine, DevOptions } from "@rollipop/rolldown/experimental";
4
4
 
@@ -49,6 +49,7 @@ interface BuildOptions {
49
49
  }
50
50
  type DevEngine$1 = DevEngine & {
51
51
  getContext: () => BundlerContext;
52
+ triggerFullBuild: () => void | Promise<void>;
52
53
  };
53
54
  type DevEngineOptions = Omit<DevOptions, 'watch'> & {
54
55
  /**