rollipop 0.1.0-dev.20260424074146 → 1.0.0-alpha.21

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/index.js CHANGED
@@ -9,7 +9,7 @@ import wrapAnsi from "wrap-ansi";
9
9
  import * as c12 from "c12";
10
10
  import * as rolldown from "@rollipop/rolldown";
11
11
  import * as rolldownExperimental from "@rollipop/rolldown/experimental";
12
- import { dev, rollipopReactRefreshWrapperPlugin } from "@rollipop/rolldown/experimental";
12
+ import { dev, rollipopReactNativePlugin, rollipopReactRefreshWrapperPlugin } from "@rollipop/rolldown/experimental";
13
13
  import gradient from "gradient-string";
14
14
  import crypto, { randomUUID } from "node:crypto";
15
15
  import "@node-rs/xxhash";
@@ -37,7 +37,6 @@ import mime from "mime";
37
37
  import Ajv from "ajv";
38
38
  import { codeFrameColumns } from "@babel/code-frame";
39
39
  import * as ws from "ws";
40
- import { transform as transform$1 } from "@svgr/core";
41
40
  import * as babel from "@babel/core";
42
41
  import * as swc from "@swc/core";
43
42
  import { Command, program } from "@commander-js/extra-typings";
@@ -89,8 +88,25 @@ async function stripFlowTypes(id, code) {
89
88
  }
90
89
  //#endregion
91
90
  //#region src/constants.ts
92
- const ROLLIPOP_VERSION = "0.1.0-dev.20260424074146";
93
- const GLOBAL_IDENTIFIER = "__ROLLIPOP_GLOBAL__";
91
+ var constants_exports = /* @__PURE__ */ __exportAll({
92
+ DEFAULT_ASSET_EXTENSIONS: () => DEFAULT_ASSET_EXTENSIONS,
93
+ DEFAULT_ASSET_REGISTRY_PATH: () => DEFAULT_ASSET_REGISTRY_PATH,
94
+ DEFAULT_ENV_FILE: () => DEFAULT_ENV_FILE,
95
+ DEFAULT_ENV_PREFIX: () => DEFAULT_ENV_PREFIX,
96
+ DEFAULT_HMR_CLIENT_PATH: () => DEFAULT_HMR_CLIENT_PATH,
97
+ DEFAULT_IMAGE_EXTENSIONS: () => DEFAULT_IMAGE_EXTENSIONS,
98
+ DEFAULT_REACT_NATIVE_GLOBAL_IDENTIFIERS: () => DEFAULT_REACT_NATIVE_GLOBAL_IDENTIFIERS,
99
+ DEFAULT_RESOLVER_ALIAS_FIELDS: () => DEFAULT_RESOLVER_ALIAS_FIELDS,
100
+ DEFAULT_RESOLVER_CONDITION_NAMES: () => DEFAULT_RESOLVER_CONDITION_NAMES,
101
+ DEFAULT_RESOLVER_MAIN_FIELDS: () => DEFAULT_RESOLVER_MAIN_FIELDS,
102
+ DEFAULT_RUNTIME_TARGET: () => DEFAULT_RUNTIME_TARGET,
103
+ DEFAULT_SOURCE_EXTENSIONS: () => DEFAULT_SOURCE_EXTENSIONS,
104
+ GLOBAL_IDENTIFIER: () => GLOBAL_IDENTIFIER,
105
+ IMAGE_EXTENSIONS: () => IMAGE_EXTENSIONS,
106
+ ROLLIPOP_VERSION: () => ROLLIPOP_VERSION
107
+ });
108
+ const ROLLIPOP_VERSION = "1.0.0-alpha.21";
109
+ const GLOBAL_IDENTIFIER = "global";
94
110
  /**
95
111
  * @see {@link https://github.com/facebook/metro/blob/0.81.x/docs/Configuration.md#resolvermainfields}
96
112
  */
@@ -99,11 +115,8 @@ const DEFAULT_RESOLVER_MAIN_FIELDS = [
99
115
  "browser",
100
116
  "main"
101
117
  ];
102
- const DEFAULT_RESOLVER_CONDITION_NAMES = [
103
- "react-native",
104
- "import",
105
- "require"
106
- ];
118
+ const DEFAULT_RESOLVER_ALIAS_FIELDS = [["react-native"], ["browser"]];
119
+ const DEFAULT_RESOLVER_CONDITION_NAMES = ["react-native"];
107
120
  /**
108
121
  * Unlike the Metro bundler configuration, this prioritizes resolving TypeScript and ESM first.
109
122
  *
@@ -119,7 +132,7 @@ const DEFAULT_SOURCE_EXTENSIONS = [
119
132
  "cjs",
120
133
  "json"
121
134
  ];
122
- const DEFAULT_ASSET_EXTENSIONS = [
135
+ const DEFAULT_IMAGE_EXTENSIONS = [
123
136
  "bmp",
124
137
  "gif",
125
138
  "jpg",
@@ -127,7 +140,15 @@ const DEFAULT_ASSET_EXTENSIONS = [
127
140
  "png",
128
141
  "psd",
129
142
  "svg",
130
- "webp",
143
+ "webp"
144
+ ];
145
+ const IMAGE_EXTENSIONS = [
146
+ ...DEFAULT_IMAGE_EXTENSIONS,
147
+ "tiff",
148
+ "ktx"
149
+ ];
150
+ const DEFAULT_ASSET_EXTENSIONS = [
151
+ ...DEFAULT_IMAGE_EXTENSIONS,
131
152
  "xml",
132
153
  "m4v",
133
154
  "mov",
@@ -152,6 +173,7 @@ const DEFAULT_ASSET_EXTENSIONS = [
152
173
  const DEFAULT_ASSET_REGISTRY_PATH = "react-native/Libraries/Image/AssetRegistry.js";
153
174
  const DEFAULT_HMR_CLIENT_PATH = "react-native/Libraries/Utilities/HMRClient.js";
154
175
  const DEFAULT_REACT_NATIVE_GLOBAL_IDENTIFIERS = [
176
+ GLOBAL_IDENTIFIER,
155
177
  "Promise",
156
178
  "regeneratorRuntime",
157
179
  "XMLHttpRequest",
@@ -206,6 +228,7 @@ const DEFAULT_REACT_NATIVE_GLOBAL_IDENTIFIERS = [
206
228
  "TaskAttributionTiming"
207
229
  ];
208
230
  const DEFAULT_ENV_PREFIX = "ROLLIPOP_";
231
+ const DEFAULT_ENV_FILE = ".env";
209
232
  const DEFAULT_RUNTIME_TARGET = "hermes-v1";
210
233
  //#endregion
211
234
  //#region src/internal/react-native.ts
@@ -244,6 +267,16 @@ function resolvePackagePath(basePath, packageName) {
244
267
  } catch {}
245
268
  throw new Error(`Failed to resolve package path for '${packageName}'`);
246
269
  }
270
+ function resolvePackageJson(basePath, packageName) {
271
+ try {
272
+ const packagePath = resolvePackagePath(basePath, packageName);
273
+ const packageJsonPath = path.join(packagePath, "package.json");
274
+ const rawPackageJson = fs.readFileSync(packageJsonPath, "utf-8");
275
+ return JSON.parse(rawPackageJson);
276
+ } catch {
277
+ return null;
278
+ }
279
+ }
247
280
  function resolvePackagePathWithNodeRequire(basePath, packageName, subpath) {
248
281
  const resolvedPath = __require.resolve(subpath ? `${packageName}/${subpath}` : packageName, { paths: [basePath] });
249
282
  const root = path.parse(resolvedPath).root;
@@ -669,17 +702,15 @@ async function getDefaultConfig(projectRoot, mode) {
669
702
  sourceExtensions: DEFAULT_SOURCE_EXTENSIONS,
670
703
  assetExtensions: DEFAULT_ASSET_EXTENSIONS,
671
704
  mainFields: DEFAULT_RESOLVER_MAIN_FIELDS,
705
+ aliasFields: DEFAULT_RESOLVER_ALIAS_FIELDS,
672
706
  conditionNames: DEFAULT_RESOLVER_CONDITION_NAMES,
673
707
  preferNativePlatform: true,
674
708
  symlinks: true
675
709
  },
676
- transformer: {
677
- svg: true,
678
- flow: { filter: {
679
- id: /\.jsx?$/,
680
- code: /@flow/
681
- } }
682
- },
710
+ transformer: { flow: { filter: {
711
+ id: /\.jsx?$/,
712
+ code: /@flow/
713
+ } } },
683
714
  serializer: {
684
715
  prelude: [getInitializeCorePath(projectRoot)],
685
716
  polyfills: await Promise.all(getPolyfillScriptPaths(reactNativePath).map(async (path) => {
@@ -710,8 +741,10 @@ async function getDefaultConfig(projectRoot, mode) {
710
741
  return "compat";
711
742
  })() },
712
743
  envDir: projectRoot,
744
+ envFile: DEFAULT_ENV_FILE,
713
745
  envPrefix: DEFAULT_ENV_PREFIX,
714
- runtimeTarget: DEFAULT_RUNTIME_TARGET
746
+ runtimeTarget: DEFAULT_RUNTIME_TARGET,
747
+ experimental: { nativeTransformPipeline: false }
715
748
  };
716
749
  }
717
750
  //#endregion
@@ -741,6 +774,22 @@ function printPluginLog(level, log, pluginName = "unknown") {
741
774
  else pluginLogger[level](pluginLabel, log.stack ?? log.message);
742
775
  }
743
776
  //#endregion
777
+ //#region src/config/compose-override.ts
778
+ async function applyOverrideRolldownOptions(override, rolldownOptions) {
779
+ if (typeof override === "function") return await override(rolldownOptions);
780
+ return {
781
+ input: merge(rolldownOptions.input ?? {}, override.input ?? {}),
782
+ output: merge(rolldownOptions.output ?? {}, override.output ?? {})
783
+ };
784
+ }
785
+ function composeOverrideRolldownOptions(target, source) {
786
+ if (source == null) return target;
787
+ if (target == null) return source;
788
+ return async (rolldownOptions) => {
789
+ return await applyOverrideRolldownOptions(source, await applyOverrideRolldownOptions(target, rolldownOptions));
790
+ };
791
+ }
792
+ //#endregion
744
793
  //#region src/config/merge-config.ts
745
794
  function mergeConfig(baseConfig, ...overrideConfigs) {
746
795
  let mergedConfig = baseConfig;
@@ -753,6 +802,7 @@ function mergeConfig(baseConfig, ...overrideConfigs) {
753
802
  "plugins"
754
803
  ].includes(key)) return Array.from(new Set([...target ?? [], ...source ?? []]));
755
804
  if (key === "reporter") return source ?? target;
805
+ if (key === "dangerously_overrideRolldownOptions") return composeOverrideRolldownOptions(target, source);
756
806
  });
757
807
  return mergedConfig;
758
808
  }
@@ -779,11 +829,13 @@ async function loadConfig(options = {}) {
779
829
  ...commonOptions
780
830
  });
781
831
  const plugins = await flattenPluginOption(userConfig.plugins);
782
- const pluginConfig = await resolvePluginConfig(userConfig, plugins);
783
- const resolvedConfig = mergeConfig(defaultConfig, ...[{
784
- ...userConfig,
832
+ const resolvedConfig = {
833
+ ...await resolvePluginConfig(mergeConfig(defaultConfig, {
834
+ ...userConfig,
835
+ plugins
836
+ }), plugins),
785
837
  plugins
786
- }, pluginConfig]);
838
+ };
787
839
  await invokeConfigResolved(resolvedConfig, plugins);
788
840
  return resolvedConfig;
789
841
  }
@@ -794,13 +846,16 @@ async function flattenPluginOption(pluginOption) {
794
846
  return [awaitedPluginOption];
795
847
  }
796
848
  async function resolvePluginConfig(baseConfig, plugins) {
797
- let mergedConfig = omit(baseConfig, ["plugins", "dangerously_overrideRolldownOptions"]);
849
+ let mergedConfig = omit(baseConfig, ["plugins"]);
798
850
  for (const plugin of plugins) {
799
851
  const context = createPluginContext(plugin.name);
852
+ const overrideBefore = mergedConfig.dangerously_overrideRolldownOptions;
800
853
  if (typeof plugin.config === "function") {
801
854
  const config = await plugin.config.call(context, mergedConfig);
802
855
  if (config != null) mergedConfig = mergeConfig(mergedConfig, config);
803
856
  } else if (typeof plugin.config === "object") mergedConfig = mergeConfig(mergedConfig, plugin.config);
857
+ const overrideAfter = mergedConfig.dangerously_overrideRolldownOptions;
858
+ if (overrideAfter != null && overrideAfter !== overrideBefore) context.debug({ message: `set 'dangerously_overrideRolldownOptions'` });
804
859
  }
805
860
  return mergedConfig;
806
861
  }
@@ -974,9 +1029,6 @@ function indent(text, indent, space = " ") {
974
1029
  function asLiteral(value) {
975
1030
  return JSON.stringify(value);
976
1031
  }
977
- function asIdentifier(name) {
978
- return name;
979
- }
980
1032
  function nodeEnvironment(dev) {
981
1033
  return dev ? "development" : "production";
982
1034
  }
@@ -1040,6 +1092,14 @@ function defineEnvFromObject(env) {
1040
1092
  return Object.fromEntries(Object.entries(env).map(([key, value]) => [`import.meta.env.${key}`, asLiteral(value)]));
1041
1093
  }
1042
1094
  //#endregion
1095
+ //#region src/utils/runtime-target.ts
1096
+ function resolveRuntimeTarget(target) {
1097
+ switch (target) {
1098
+ case "hermes": return "Hermes";
1099
+ default: return "HermesV1";
1100
+ }
1101
+ }
1102
+ //#endregion
1043
1103
  //#region src/utils/server.ts
1044
1104
  function getBaseUrl(host, port, https) {
1045
1105
  return `${https ? "https" : "http"}://${host}:${port}`;
@@ -1052,17 +1112,18 @@ function getBuildTotalModules(storage, id) {
1052
1112
  //#endregion
1053
1113
  //#region src/core/env.ts
1054
1114
  function loadEnv(options) {
1055
- const { envDir, envPrefix, mode } = options;
1115
+ const { envDir, envPrefix, envFile, mode } = options;
1056
1116
  invariant(envPrefix.length > 0, "`envPrefix` is required");
1117
+ invariant(envFile.length > 0, "`envFile` is required");
1057
1118
  const env = {};
1058
1119
  const envFilesToLoad = [
1059
- `.env`,
1060
- `.env.local`,
1061
- mode ? `.env.${mode}` : null,
1062
- mode ? `.env.${mode}.local` : null
1120
+ envFile,
1121
+ `${envFile}.local`,
1122
+ mode ? `${envFile}.${mode}` : null,
1123
+ mode ? `${envFile}.${mode}.local` : null
1063
1124
  ].filter(isNotNil);
1064
- for (const envFile of envFilesToLoad) {
1065
- const envPath = path.resolve(envDir, envFile);
1125
+ for (const file of envFilesToLoad) {
1126
+ const envPath = path.resolve(envDir, file);
1066
1127
  if (!fs.existsSync(envPath)) continue;
1067
1128
  logger$2.trace(`Loading environment variables from ${envPath}`);
1068
1129
  const parsed = dotenv.parse(fs.readFileSync(envPath, "utf-8"));
@@ -1208,7 +1269,7 @@ var FileSystemBundleStore = class {
1208
1269
  code,
1209
1270
  mtimeMs: stats.mtimeMs
1210
1271
  };
1211
- logger$2.info(`File system bundle created at ${bundleFilePath}`);
1272
+ logger$2.debug(`File system bundle created at ${bundleFilePath}`);
1212
1273
  }
1213
1274
  update() {
1214
1275
  this.holder = {
@@ -2423,6 +2484,7 @@ var assets_exports = /* @__PURE__ */ __exportAll({
2423
2484
  stripSuffix: () => stripSuffix
2424
2485
  });
2425
2486
  const SCALE_PATTERN = "@(\\d+\\.?\\d*)x";
2487
+ const IMAGE_ASSET_TYPES = new Set(IMAGE_EXTENSIONS);
2426
2488
  /**
2427
2489
  * key: platform,
2428
2490
  * value: allowed scales
@@ -2452,6 +2514,7 @@ async function resolveScaledAssets(options) {
2452
2514
  preferNativePlatform
2453
2515
  };
2454
2516
  const extension = path.extname(assetPath);
2517
+ const type = extension.substring(1);
2455
2518
  const relativePath = path.relative(projectRoot, assetPath);
2456
2519
  const dirname = path.dirname(assetPath);
2457
2520
  const files = fs.readdirSync(dirname);
@@ -2469,7 +2532,7 @@ async function resolveScaledAssets(options) {
2469
2532
  }
2470
2533
  if (!(Object.keys(scaledAssets).length && scaledAssets[1])) throw new Error(`cannot resolve base asset of ${assetPath}`);
2471
2534
  const imageData = fs.readFileSync(assetPath);
2472
- const dimensions = imageSize(imageData);
2535
+ const dimensions = IMAGE_ASSET_TYPES.has(type) ? imageSize(imageData) : void 0;
2473
2536
  const filteredScaledAssets = Object.entries(scaledAssets).map(([scale, file]) => ({
2474
2537
  scale: parseFloat(scale),
2475
2538
  file
@@ -2485,9 +2548,9 @@ async function resolveScaledAssets(options) {
2485
2548
  __packager_asset: true,
2486
2549
  id: assetPath,
2487
2550
  name: stripedBasename.replace(extension, ""),
2488
- type: extension.substring(1),
2489
- width: dimensions.width,
2490
- height: dimensions.height,
2551
+ type,
2552
+ width: dimensions?.width,
2553
+ height: dimensions?.height,
2491
2554
  files: filteredScaledAssets.files,
2492
2555
  scales: filteredScaledAssets.scales,
2493
2556
  fileSystemLocation: path.dirname(assetPath),
@@ -2690,8 +2753,8 @@ function withTransformBoundary(context, plugins) {
2690
2753
  }
2691
2754
  //#endregion
2692
2755
  //#region src/core/plugins/react-native-plugin.ts
2693
- function reactNativePlugin(config, options) {
2694
- const { buildType, flowFilter, codegenFilter, assetsDir, assetExtensions, assetRegistryPath, hmrClientPath } = options;
2756
+ function reactNativePlugin(options) {
2757
+ const { projectRoot, platform, preferNativePlatform, buildType, assetsDir, assetExtensions, assetRegistryPath, flowFilter, codegenFilter, builtinPluginConfig } = options;
2695
2758
  const codegenPlugin = {
2696
2759
  name: "rollipop:react-native-codegen-marker",
2697
2760
  transform: {
@@ -2728,10 +2791,10 @@ function reactNativePlugin(config, options) {
2728
2791
  async handler(id) {
2729
2792
  this.debug(`Asset ${id} found`);
2730
2793
  const assetData = await resolveScaledAssets({
2731
- projectRoot: config.root,
2794
+ projectRoot,
2732
2795
  assetPath: id,
2733
- platform: options.platform,
2734
- preferNativePlatform: config.resolver.preferNativePlatform
2796
+ platform,
2797
+ preferNativePlatform
2735
2798
  });
2736
2799
  assets.push(assetData);
2737
2800
  return {
@@ -2751,33 +2814,13 @@ function reactNativePlugin(config, options) {
2751
2814
  await copyAssetsToDestination({
2752
2815
  assets,
2753
2816
  assetsDir,
2754
- platform: options.platform,
2755
- preferNativePlatform: config.resolver.preferNativePlatform
2817
+ platform,
2818
+ preferNativePlatform
2756
2819
  });
2757
2820
  }
2758
2821
  }
2759
2822
  };
2760
- const defaultRuntimeImplements = getDefaultRuntimeImplements();
2761
- const hmrConfig = resolveHmrConfig(config);
2762
- const replaceHMRClientPlugin = {
2763
- name: "rollipop:react-native-replace-hmr-client",
2764
- load: {
2765
- filter: [include(id(exactRegex(hmrClientPath)))],
2766
- handler(id) {
2767
- this.debug(`Replacing HMR client: ${id}`);
2768
- return {
2769
- code: hmrConfig?.clientImplement ?? defaultRuntimeImplements.clientImplement,
2770
- moduleType: "ts"
2771
- };
2772
- }
2773
- }
2774
- };
2775
- return [
2776
- codegenPlugin,
2777
- stripFlowSyntaxPlugin,
2778
- assetPlugin,
2779
- ...(buildType === "serve" ? [replaceHMRClientPlugin] : null) ?? []
2780
- ];
2823
+ return [...builtinPluginConfig ? [rollipopReactNativePlugin(builtinPluginConfig)] : [codegenPlugin, stripFlowSyntaxPlugin], assetPlugin];
2781
2824
  }
2782
2825
  //#endregion
2783
2826
  //#region src/core/plugins/prelude-plugin.ts
@@ -2830,42 +2873,9 @@ function jsonPlugin() {
2830
2873
  };
2831
2874
  }
2832
2875
  //#endregion
2833
- //#region src/core/plugins/svg-plugin.ts
2834
- function svgPlugin(options) {
2835
- if (!options.enabled) return null;
2836
- return {
2837
- name: "rollipop:svg",
2838
- load: {
2839
- filter: { id: /\.svg$/ },
2840
- async handler(id) {
2841
- return {
2842
- code: await transform$1(fs.readFileSync(id, "utf-8"), {
2843
- template: defaultTemplate,
2844
- plugins: [__require.resolve("@svgr/plugin-jsx")],
2845
- native: true
2846
- }, { filePath: id }),
2847
- moduleType: "jsx"
2848
- };
2849
- }
2850
- }
2851
- };
2852
- }
2853
- const SVG_COMPONENT_NAME = "SvgLogo";
2854
- const defaultTemplate = (variables, { tpl }) => {
2855
- return tpl`${variables.imports};
2856
-
2857
- ${variables.interfaces};
2858
-
2859
- const ${SVG_COMPONENT_NAME} = (${variables.props}) => (
2860
- ${variables.jsx}
2861
- );
2862
-
2863
- export default ${SVG_COMPONENT_NAME};`;
2864
- };
2865
- //#endregion
2866
2876
  //#region src/utils/babel.ts
2867
- function mergeBabelOptions(baseOptions, ...options) {
2868
- return options.reduce((acc, options) => mergeWith(acc, options, merge$2), baseOptions);
2877
+ function mergeBabelOptions(options) {
2878
+ return options.reduce((acc, options) => mergeWith(acc, options, merge$2), {});
2869
2879
  }
2870
2880
  function merge$2(target, source, key) {
2871
2881
  if (key === "plugins") return [...target ?? [], ...source ?? []];
@@ -2882,8 +2892,8 @@ function isJSX(id) {
2882
2892
  }
2883
2893
  //#endregion
2884
2894
  //#region src/core/plugins/babel-plugin.ts
2885
- function babelPlugin(options) {
2886
- const { rules = [] } = options ?? {};
2895
+ function babelPlugin({ useNativeTransformPipeline, transformConfig }) {
2896
+ const { rules = [] } = transformConfig ?? {};
2887
2897
  const babelOptionsById = /* @__PURE__ */ new Map();
2888
2898
  const babelRules = rules.map(({ filter, options }, index) => {
2889
2899
  return {
@@ -2907,14 +2917,14 @@ function babelPlugin(options) {
2907
2917
  const flags = getFlag(this, id);
2908
2918
  if (flags & TransformFlag.SKIP_ALL) return;
2909
2919
  const babelOptions = babelOptionsById.get(id) ?? [];
2910
- if (!(flags & TransformFlag.CODEGEN_REQUIRED || babelOptions.length > 0)) return;
2911
- const baseOptions = getPreset(flags, id);
2920
+ if (!(useNativeTransformPipeline ? babelOptions.length > 0 : flags & TransformFlag.CODEGEN_REQUIRED || babelOptions.length > 0)) return;
2921
+ const baseOptions = useNativeTransformPipeline ? [] : [getPreset(flags, id)];
2912
2922
  const result = babel.transformSync(code, {
2913
2923
  filename: id,
2914
2924
  babelrc: false,
2915
2925
  configFile: false,
2916
2926
  sourceMaps: true,
2917
- ...mergeBabelOptions(baseOptions, ...babelOptions)
2927
+ ...mergeBabelOptions([...baseOptions, ...babelOptions])
2918
2928
  });
2919
2929
  invariant(result?.code, `Failed to transform with babel: ${id}`);
2920
2930
  return {
@@ -2949,8 +2959,8 @@ function getPreset(flags, id) {
2949
2959
  }
2950
2960
  //#endregion
2951
2961
  //#region src/utils/swc.ts
2952
- function mergeSwcOptions(baseOptions, ...options) {
2953
- return options.reduce((acc, options) => mergeWith(acc, options, merge$1), baseOptions);
2962
+ function mergeSwcOptions(options) {
2963
+ return options.reduce((acc, options) => mergeWith(acc, options, merge$1), {});
2954
2964
  }
2955
2965
  function merge$1(target, source, key) {
2956
2966
  if (key === "plugins") return [...target ?? [], ...source ?? []];
@@ -2960,8 +2970,8 @@ function merge$1(target, source, key) {
2960
2970
  const ROLLDOWN_RUNTIME_EXCLUDE_FILTER = exclude(or(id(/rolldown\/runtime/), id(/@oxc-project\+runtime/)));
2961
2971
  //#endregion
2962
2972
  //#region src/core/plugins/swc-plugin.ts
2963
- function swcPlugin(runtimeTarget, options) {
2964
- const { rules = [] } = options ?? {};
2973
+ function swcPlugin({ useNativeTransformPipeline, runtimeTarget, transformConfig }) {
2974
+ const { rules = [] } = transformConfig ?? {};
2965
2975
  const swcOptionsById = /* @__PURE__ */ new Map();
2966
2976
  const swcHelpersResolvePlugin = {
2967
2977
  name: "rollipop:swc-helpers-resolve",
@@ -2986,7 +2996,7 @@ function swcPlugin(runtimeTarget, options) {
2986
2996
  }
2987
2997
  };
2988
2998
  });
2989
- const getSwcPreset = presets[runtimeTarget];
2999
+ const getSwcPreset = useNativeTransformPipeline ? null : presets[runtimeTarget];
2990
3000
  const swcPlugin = {
2991
3001
  name: "rollipop:swc",
2992
3002
  buildStart() {
@@ -2997,14 +3007,15 @@ function swcPlugin(runtimeTarget, options) {
2997
3007
  handler(code, id) {
2998
3008
  if (getFlag(this, id) & TransformFlag.SKIP_ALL) return;
2999
3009
  const swcOptions = swcOptionsById.get(id) ?? [];
3000
- const baseOptions = getSwcPreset(id);
3010
+ if (getSwcPreset == null && swcOptions.length === 0) return;
3011
+ const baseOptions = getSwcPreset != null ? [getSwcPreset(id)] : [];
3001
3012
  const result = swc.transformSync(code, {
3002
3013
  filename: id,
3003
3014
  configFile: false,
3004
3015
  swcrc: false,
3005
3016
  sourceMaps: true,
3006
3017
  inputSourceMap: false,
3007
- ...mergeSwcOptions(baseOptions, ...swcOptions)
3018
+ ...mergeSwcOptions([...baseOptions, ...swcOptions])
3008
3019
  });
3009
3020
  return {
3010
3021
  code: result.code,
@@ -3109,14 +3120,37 @@ function reporterPlugin(options) {
3109
3120
  };
3110
3121
  }
3111
3122
  //#endregion
3123
+ //#region src/core/plugins/dev-server-plugin.ts
3124
+ async function devServerPlugin(options) {
3125
+ const { cwd, hmrClientPath, hmrConfig } = options;
3126
+ if (hmrConfig == null) return null;
3127
+ return [{
3128
+ name: "rollipop:replace-hmr-client",
3129
+ load: {
3130
+ filter: [include(id(exactRegex(resolveFrom(cwd, typeof hmrClientPath === "function" ? await hmrClientPath(cwd) : hmrClientPath))))],
3131
+ handler(id) {
3132
+ this.debug(`Replacing HMR client: ${id}`);
3133
+ return {
3134
+ code: hmrConfig.clientImplement,
3135
+ moduleType: "ts"
3136
+ };
3137
+ }
3138
+ }
3139
+ }, rollipopReactRefreshWrapperPlugin({
3140
+ cwd,
3141
+ include: [/\.[tj]sx?(?:$|\?)/],
3142
+ exclude: [/\/node_modules\//]
3143
+ })];
3144
+ }
3145
+ //#endregion
3112
3146
  //#region src/core/plugins/index.ts
3113
3147
  var plugins_exports = /* @__PURE__ */ __exportAll({
3114
3148
  babel: () => babelPlugin,
3149
+ devServer: () => devServerPlugin,
3115
3150
  json: () => jsonPlugin,
3116
3151
  prelude: () => preludePlugin,
3117
3152
  reactNative: () => reactNativePlugin,
3118
3153
  reporter: () => reporterPlugin,
3119
- svg: () => svgPlugin,
3120
3154
  swc: () => swcPlugin
3121
3155
  });
3122
3156
  //#endregion
@@ -3133,18 +3167,18 @@ async function resolveRolldownOptions(context, config, buildOptions, devEngineOp
3133
3167
  MODE: config.mode,
3134
3168
  ...isDevServerMode ? { BASE_URL: getBaseUrl(devEngineOptions.host, devEngineOptions.port, devEngineOptions.https) } : null
3135
3169
  };
3170
+ const hmrConfig = resolveHmrConfig(config);
3171
+ const hmrEnabled = hmrConfig != null;
3136
3172
  const { sourceExtensions, assetExtensions, preferNativePlatform, external: rolldownExternal, ...rolldownResolve } = config.resolver;
3137
- const { polyfills, prelude: preludePaths, banner: rolldownBanner, footer: rolldownFooter, postBanner: rolldownPostBanner, postFooter: rolldownPostFooter, intro: rolldownIntro, outro: rolldownOutro, shimMissingExports: rolldownShimMissingExports } = config.serializer;
3138
- const { flow, babel: babelConfig, swc: swcConfig, ...rolldownTransform } = config.transformer;
3173
+ const { polyfills, banner: rolldownBanner, footer: rolldownFooter, postBanner: rolldownPostBanner, postFooter: rolldownPostFooter, intro: rolldownIntro, outro: rolldownOutro, shimMissingExports: rolldownShimMissingExports } = config.serializer;
3174
+ const { flow: _flow, babel: _babel, swc: _swc, ...rolldownTransform } = config.transformer;
3139
3175
  const { treeshake: rolldownTreeshake, minify: rolldownMinify, lazyBarrel: rolldownLazyBarrel, ...rolldownOptimization } = config.optimization;
3140
- const { codegen, assetRegistryPath, hmrClientPath, globalIdentifiers: rolldownGlobalIdentifiers } = config.reactNative;
3176
+ const { globalIdentifiers: rolldownGlobalIdentifiers } = config.reactNative;
3141
3177
  const { sourcemap: rolldownSourcemap, sourcemapBaseUrl: rolldownSourcemapBaseUrl, sourcemapDebugIds: rolldownSourcemapDebugIds, sourcemapIgnoreList: rolldownSourcemapIgnoreList, sourcemapPathTransform: rolldownSourcemapPathTransform } = config;
3142
- const transformSvg = config.transformer.svg;
3143
- const resolvedSourceExtensions = transformSvg ? [...sourceExtensions, "svg"] : sourceExtensions;
3144
- const resolvedAssetExtensions = transformSvg ? assetExtensions.filter((extension) => extension !== "svg") : assetExtensions;
3178
+ const userPlugins = config.plugins;
3145
3179
  const mergedResolveOptions = merge({ extensions: getResolveExtensions({
3146
- sourceExtensions: resolvedSourceExtensions,
3147
- assetExtensions: resolvedAssetExtensions,
3180
+ sourceExtensions,
3181
+ assetExtensions,
3148
3182
  platform,
3149
3183
  preferNativePlatform
3150
3184
  }) }, rolldownResolve);
@@ -3157,29 +3191,20 @@ async function resolveRolldownOptions(context, config, buildOptions, devEngineOp
3157
3191
  },
3158
3192
  define: {
3159
3193
  __DEV__: asLiteral(dev),
3160
- global: asIdentifier(GLOBAL_IDENTIFIER),
3161
3194
  "process.env.NODE_ENV": asLiteral(nodeEnvironment(dev)),
3162
3195
  "process.env.DEBUG_ROLLIPOP": asLiteral(isDebugEnabled()),
3196
+ ...hmrEnabled ? null : { "import.meta.hot": "{}" },
3163
3197
  ...defineEnvFromObject(env),
3164
3198
  ...defineEnvFromObject(builtInEnv)
3165
3199
  },
3166
3200
  helpers: { mode: "Runtime" }
3167
3201
  }, rolldownTransform);
3168
- const devServerPlugins = isDevServerMode ? [rollipopReactRefreshWrapperPlugin({
3169
- cwd: config.root,
3170
- include: [/\.[tj]sx?(?:$|\?)/],
3171
- exclude: [/\/node_modules\//]
3172
- })] : null;
3173
- const defaultReporters = [(() => {
3174
- switch (config.terminal.status) {
3175
- case "compat": return new CompatStatusReporter();
3176
- case "progress": return new ProgressBarStatusReporter(context.id, `[${platform}, ${buildOptions.dev ? "dev" : "prod"}]`, getBuildTotalModules(context.storage, context.id));
3177
- }
3178
- })()];
3179
- const reporterOptions = {
3180
- initialTotalModules: getBuildTotalModules(context.storage, context.id),
3181
- reporter: mergeReporters([...defaultReporters, config.reporter].filter(isNotNil))
3182
- };
3202
+ const preludePluginOptions = resolvePreludePluginOptions(config);
3203
+ const reactNativePluginOptions = await resolveReactNativePluginOptions(config, context, buildOptions);
3204
+ const babelPluginOptions = resolveBabelPluginOptions(config);
3205
+ const swcPluginOptions = resolveSwcPluginOptions(config);
3206
+ const devServerPluginOptions = resolveDevServerPluginOptions(config, hmrConfig);
3207
+ const reporterPluginOptions = resolveReporterPluginOptions(config, context, buildOptions);
3183
3208
  const finalOptions = await applyDangerouslyOverrideOptionsFinalizer(config, {
3184
3209
  platform: "neutral",
3185
3210
  cwd: config.root,
@@ -3190,31 +3215,20 @@ async function resolveRolldownOptions(context, config, buildOptions, devEngineOp
3190
3215
  treeshake: rolldownTreeshake,
3191
3216
  external: rolldownExternal,
3192
3217
  shimMissingExports: rolldownShimMissingExports,
3193
- optimization: {
3194
- ...rolldownOptimization,
3195
- inlineConst: false
3218
+ optimization: rolldownOptimization,
3219
+ experimental: {
3220
+ lazyBarrel: rolldownLazyBarrel,
3221
+ ...isDevServerMode ? { devMode: hmrConfig ? { implement: hmrConfig.runtimeImplement } : false } : null
3196
3222
  },
3197
- experimental: { lazyBarrel: rolldownLazyBarrel },
3198
3223
  plugins: withTransformBoundary(context, [
3199
- preludePlugin({ modulePaths: preludePaths }),
3200
- reactNativePlugin(config, {
3201
- dev,
3202
- platform,
3203
- buildType: context.buildType,
3204
- codegenFilter: codegen.filter,
3205
- flowFilter: flow.filter,
3206
- assetsDir: buildOptions.assetsDir,
3207
- assetExtensions: resolvedAssetExtensions,
3208
- assetRegistryPath: resolveFrom(config.root, typeof assetRegistryPath === "function" ? await assetRegistryPath(config.root) : assetRegistryPath),
3209
- hmrClientPath: resolveFrom(config.root, typeof hmrClientPath === "function" ? await hmrClientPath(config.root) : hmrClientPath)
3210
- }),
3224
+ preludePlugin(preludePluginOptions),
3225
+ reactNativePlugin(reactNativePluginOptions),
3211
3226
  jsonPlugin(),
3212
- svgPlugin({ enabled: transformSvg }),
3213
- babelPlugin(babelConfig),
3214
- swcPlugin(config.runtimeTarget, swcConfig),
3215
- reporterPlugin(reporterOptions),
3216
- devServerPlugins,
3217
- config.plugins
3227
+ babelPlugin(babelPluginOptions),
3228
+ swcPlugin(swcPluginOptions),
3229
+ devServerPlugin(devServerPluginOptions),
3230
+ reporterPlugin(reporterPluginOptions),
3231
+ userPlugins
3218
3232
  ]),
3219
3233
  checks: {
3220
3234
  eval: false,
@@ -3246,7 +3260,7 @@ async function resolveRolldownOptions(context, config, buildOptions, devEngineOp
3246
3260
  sourcemapBaseUrl: rolldownSourcemapBaseUrl,
3247
3261
  sourcemapDebugIds: rolldownSourcemapDebugIds,
3248
3262
  sourcemapIgnoreList: rolldownSourcemapIgnoreList,
3249
- sourcemapPathTransform: rolldownSourcemapPathTransform,
3263
+ sourcemapPathTransform: rolldownSourcemapPathTransform ?? createProjectRootSourcemapPathTransform(config.root),
3250
3264
  codeSplitting: false,
3251
3265
  strictExecutionOrder: true,
3252
3266
  globalIdentifiers: rolldownGlobalIdentifiers,
@@ -3255,12 +3269,98 @@ async function resolveRolldownOptions(context, config, buildOptions, devEngineOp
3255
3269
  resolveRolldownOptions.cache.set(context.id, finalOptions);
3256
3270
  return finalOptions;
3257
3271
  }
3272
+ function resolvePreludePluginOptions(config) {
3273
+ return { modulePaths: config.serializer.prelude };
3274
+ }
3275
+ async function resolveReactNativePluginOptions(config, context, buildOptions) {
3276
+ return {
3277
+ projectRoot: config.root,
3278
+ platform: buildOptions.platform,
3279
+ preferNativePlatform: config.resolver.preferNativePlatform,
3280
+ buildType: context.buildType,
3281
+ assetsDir: buildOptions.assetsDir,
3282
+ assetExtensions: config.resolver.assetExtensions,
3283
+ assetRegistryPath: await resolveAssetRegistryPath(config),
3284
+ flowFilter: config.transformer.flow?.filter ?? [],
3285
+ codegenFilter: config.reactNative.codegen?.filter ?? [],
3286
+ builtinPluginConfig: resolveReactNativeBuiltinPluginConfig(config)
3287
+ };
3288
+ }
3289
+ async function resolveAssetRegistryPath(config) {
3290
+ const { assetRegistryPath } = config.reactNative;
3291
+ const path = typeof assetRegistryPath === "function" ? await assetRegistryPath(config.root) : assetRegistryPath;
3292
+ return resolveFrom(config.root, path);
3293
+ }
3294
+ function resolveReactNativeBuiltinPluginConfig(config) {
3295
+ if (!config.experimental?.nativeTransformPipeline) return null;
3296
+ return {
3297
+ envName: config.mode,
3298
+ runtimeTarget: resolveRuntimeTarget(config.runtimeTarget),
3299
+ flow: config.experimental.flow,
3300
+ worklets: resolveWorkletsConfig(config)
3301
+ };
3302
+ }
3303
+ function resolveWorkletsConfig(config) {
3304
+ const { worklets } = config.experimental ?? {};
3305
+ if (worklets == null) return;
3306
+ return merge({
3307
+ isRelease: config.mode === "production",
3308
+ pluginVersion: resolvePackageJson(config.root, "react-native-worklets")?.version
3309
+ }, worklets);
3310
+ }
3311
+ function resolveBabelPluginOptions(config) {
3312
+ return {
3313
+ useNativeTransformPipeline: config.experimental?.nativeTransformPipeline,
3314
+ transformConfig: config.transformer.babel
3315
+ };
3316
+ }
3317
+ function resolveSwcPluginOptions(config) {
3318
+ return {
3319
+ useNativeTransformPipeline: config.experimental?.nativeTransformPipeline,
3320
+ runtimeTarget: config.runtimeTarget,
3321
+ transformConfig: config.transformer.swc
3322
+ };
3323
+ }
3324
+ function resolveDevServerPluginOptions(config, hmrConfig) {
3325
+ return {
3326
+ cwd: config.root,
3327
+ hmrClientPath: config.reactNative.hmrClientPath,
3328
+ hmrConfig
3329
+ };
3330
+ }
3331
+ function resolveReporterPluginOptions(config, context, buildOptions) {
3332
+ const statusReporter = createStatusReporter(config, context, buildOptions);
3333
+ return {
3334
+ initialTotalModules: getBuildTotalModules(context.storage, context.id),
3335
+ reporter: mergeReporters([statusReporter, config.reporter].filter(isNotNil))
3336
+ };
3337
+ }
3338
+ function createStatusReporter(config, context, buildOptions) {
3339
+ switch (config.terminal.status) {
3340
+ case "compat": return new CompatStatusReporter();
3341
+ case "progress": return new ProgressBarStatusReporter(context.id, `[${buildOptions.platform}, ${buildOptions.dev ? "dev" : "prod"}]`, getBuildTotalModules(context.storage, context.id));
3342
+ }
3343
+ }
3258
3344
  function getResolveExtensions({ platform, sourceExtensions, assetExtensions, preferNativePlatform }) {
3259
3345
  const supportedExtensions = [...sourceExtensions, ...assetExtensions];
3260
3346
  return [...[platform, preferNativePlatform ? "native" : null].filter(isNotNil).map((platform) => {
3261
3347
  return supportedExtensions.map((extension) => `.${platform}.${extension}`);
3262
3348
  }), ...supportedExtensions.map((extension) => `.${extension}`)].flat();
3263
3349
  }
3350
+ /**
3351
+ * Default sourcemap path transform.
3352
+ *
3353
+ * Rolldown emits `sources` relative to the bundle output's directory, which
3354
+ * yields paths like `../App.tsx` when the bundle lives under e.g. `dist/`.
3355
+ * RN tooling (symbolication, devtools) expects project-root-relative paths,
3356
+ * so this rewrites each entry to be relative to `projectRoot`.
3357
+ */
3358
+ function createProjectRootSourcemapPathTransform(projectRoot) {
3359
+ return (source, sourcemapPath) => {
3360
+ const absolute = path.resolve(path.dirname(sourcemapPath), source);
3361
+ return path.relative(projectRoot, absolute);
3362
+ };
3363
+ }
3264
3364
  function loadPolyfills(polyfills) {
3265
3365
  return polyfills.map((polyfill) => {
3266
3366
  if (typeof polyfill === "string") return fs.readFileSync(polyfill, "utf-8");
@@ -3270,22 +3370,21 @@ function loadPolyfills(polyfills) {
3270
3370
  });
3271
3371
  }
3272
3372
  async function applyDangerouslyOverrideOptionsFinalizer(config, inputOptions, outputOptions) {
3273
- if (typeof config.dangerously_overrideRolldownOptions === "function") return await config.dangerously_overrideRolldownOptions({
3373
+ const override = config.dangerously_overrideRolldownOptions;
3374
+ if (override == null) return {
3274
3375
  input: inputOptions,
3275
3376
  output: outputOptions
3276
- });
3277
- return {
3278
- input: merge(inputOptions, config.dangerously_overrideRolldownOptions?.input ?? {}),
3279
- output: merge(outputOptions, config.dangerously_overrideRolldownOptions?.output ?? {})
3280
3377
  };
3378
+ return await applyOverrideRolldownOptions(override, {
3379
+ input: inputOptions,
3380
+ output: outputOptions
3381
+ });
3281
3382
  }
3282
- function getOverrideOptionsForDevServer(config, buildOptions) {
3283
- const hmrConfig = resolveHmrConfig(config);
3383
+ function getOverrideOptionsForDevServer(buildOptions) {
3284
3384
  return {
3285
3385
  input: {
3286
3386
  transform: { jsx: { development: true } },
3287
3387
  experimental: {
3288
- devMode: hmrConfig ? { implement: hmrConfig.runtimeImplement } : false,
3289
3388
  incrementalBuild: true,
3290
3389
  nativeMagicString: true
3291
3390
  },
@@ -3309,7 +3408,7 @@ var Bundler = class Bundler {
3309
3408
  const resolvedBuildOptions = resolveBuildOptions(config, buildOptions);
3310
3409
  const context = Bundler.createContext(buildType, config, resolvedBuildOptions);
3311
3410
  const { input = {}, output = {} } = await resolveRolldownOptions(context, config, resolvedBuildOptions, devEngineOptions);
3312
- const devServerOptions = getOverrideOptionsForDevServer(config, resolvedBuildOptions);
3411
+ const devServerOptions = getOverrideOptionsForDevServer(resolvedBuildOptions);
3313
3412
  const devEngine = await dev(merge(input, devServerOptions.input), merge(output, devServerOptions.output), {
3314
3413
  watch: config.watcher,
3315
3414
  ...devEngineOptions
@@ -3381,7 +3480,7 @@ async function runServer(config, options) {
3381
3480
  }
3382
3481
  //#endregion
3383
3482
  //#region package.json
3384
- var version = "0.1.0-dev.20260424074146";
3483
+ var version = "1.0.0-alpha.21";
3385
3484
  //#endregion
3386
3485
  //#region src/node/logger.ts
3387
3486
  const logger = new Logger("cli");
@@ -3593,9 +3692,10 @@ function assertHasNoDuplicateCommands(defaultCommands, commands) {
3593
3692
  //#endregion
3594
3693
  //#region src/node/cli-utils.ts
3595
3694
  function createCommand(commandDefinition) {
3596
- const { name, description, options, action } = commandDefinition;
3695
+ const { name, description, helpText, options, action } = commandDefinition;
3597
3696
  const command = new Command(name).description(description);
3598
3697
  if (options != null) for (const option of options) (option.required ? command.requiredOption.bind(command) : command.option.bind(command))(option.name, option.description ?? "", (value) => option.parse != null ? option.parse(value) : value, option.default);
3698
+ if (helpText != null) command.addHelpText("after", `\n${helpText}`);
3599
3699
  return command.action(withErrorHandler(async function(args) {
3600
3700
  await action.call({ platforms: ["android", "ios"] }, args);
3601
3701
  }));
@@ -3612,6 +3712,80 @@ function createReactNativeCliCommand(commandDefinition) {
3612
3712
  };
3613
3713
  }
3614
3714
  //#endregion
3715
+ //#region src/node/commands/agent/action.ts
3716
+ const defaultBaseUrl = `http://${DEFAULT_HOST}:${DEFAULT_PORT}`;
3717
+ function getAgentGuide(baseUrl = defaultBaseUrl) {
3718
+ return [
3719
+ "Rollipop Agent Guide",
3720
+ "",
3721
+ "Rollipop exposes build and runtime diagnostics through SSE and MCP.",
3722
+ "Keep the dev server running, then connect your agent to one of these endpoints.",
3723
+ "",
3724
+ "Start the dev server:",
3725
+ "",
3726
+ " rollipop start --reset-cache",
3727
+ "",
3728
+ "Default endpoints:",
3729
+ "",
3730
+ ` SSE events: ${baseUrl}/sse/events`,
3731
+ ` MCP server: ${baseUrl}/mcp`,
3732
+ ` Reset cache: ${baseUrl}/reset-cache`,
3733
+ ` Bundler status: ${baseUrl}/bundlers/<id>/status`,
3734
+ "",
3735
+ "If you start Rollipop with custom --host, --port, or --https options,",
3736
+ "adjust these URLs to match the running dev server.",
3737
+ "",
3738
+ "SSE usage:",
3739
+ "",
3740
+ ` curl -N ${baseUrl}/sse/events`,
3741
+ "",
3742
+ " Event format:",
3743
+ " event: <event_type>",
3744
+ " data: <json_payload>",
3745
+ "",
3746
+ " Useful event types:",
3747
+ " bundle_build_started, bundle_build_done, bundle_build_failed",
3748
+ " watch_change, client_log, device_connected, device_disconnected",
3749
+ " server_ready, cache_reset",
3750
+ "",
3751
+ "MCP setup:",
3752
+ "",
3753
+ " Add this to your project .mcp.json:",
3754
+ "",
3755
+ " {",
3756
+ " \"mcpServers\": {",
3757
+ " \"rollipop\": {",
3758
+ " \"type\": \"http\",",
3759
+ ` "url": "${baseUrl}/mcp"`,
3760
+ " }",
3761
+ " }",
3762
+ " }",
3763
+ "",
3764
+ " Available tools:",
3765
+ " get_build_events({ \"duration\": 10000 })",
3766
+ " reset_cache()",
3767
+ "",
3768
+ "Agent workflow:",
3769
+ "",
3770
+ " 1. Run rollipop start and keep it running.",
3771
+ " 2. Use get_build_events or subscribe to SSE before and after edits.",
3772
+ " 3. Wait for bundle_build_done or bundle_build_failed.",
3773
+ " 4. If the build fails, inspect the error payload, fix the code, and repeat.",
3774
+ " 5. Use reset_cache or /reset-cache when stale cache is suspected."
3775
+ ].join("\n");
3776
+ }
3777
+ const action$2 = async () => {
3778
+ console.log(getAgentGuide());
3779
+ };
3780
+ //#endregion
3781
+ //#region src/node/commands/agent/command.ts
3782
+ const command$2 = {
3783
+ name: "agent",
3784
+ description: "Print guidance for connecting LLM agents to Rollipop diagnostics.",
3785
+ helpText: getAgentGuide(),
3786
+ action: action$2
3787
+ };
3788
+ //#endregion
3615
3789
  //#region src/node/constants.ts
3616
3790
  const UNSUPPORTED_OPTION_DESCRIPTION = "This option is not supported by Rollipop.";
3617
3791
  //#endregion
@@ -3849,9 +4023,10 @@ var cli_exports = /* @__PURE__ */ __exportAll({ run: () => run });
3849
4023
  function run(argv) {
3850
4024
  Logo.printOnce();
3851
4025
  const cli = program.name("rollipop").version(version);
4026
+ cli.addCommand(createCommand(command$2));
3852
4027
  cli.addCommand(createCommand(command$1));
3853
4028
  cli.addCommand(createCommand(command));
3854
4029
  cli.parse(argv);
3855
4030
  }
3856
4031
  //#endregion
3857
- export { assets_exports as AssetUtils, Bundler, DEFAULT_HOST, DEFAULT_PORT, DEV_SERVER_ASSET_PATH, cli_exports as cli, createCommand, createDevServer, createReactNativeCliCommand, defineConfig, flattenPluginOption, getDefaultConfig, invokeConfigResolved, loadConfig, loadEnv, mergeConfig, plugins_exports as plugins, resetCache, resolvePluginConfig, rolldown, rolldownExperimental, runBuild, runServer, setupInteractiveMode };
4032
+ export { assets_exports as AssetUtils, Bundler, constants_exports as Constants, DEFAULT_HOST, DEFAULT_PORT, DEV_SERVER_ASSET_PATH, cli_exports as cli, createCommand, createDevServer, createReactNativeCliCommand, defineConfig, flattenPluginOption, getDefaultConfig, invokeConfigResolved, loadConfig, loadEnv, mergeConfig, plugins_exports as plugins, resetCache, resolvePluginConfig, rolldown, rolldownExperimental, runBuild, runServer, setupInteractiveMode };