rollipop 1.0.0-alpha.21 → 1.0.0-alpha.23

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 (161) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/{chunk-DEq-mXcV.js → _virtual/_rolldown/runtime.js} +1 -1
  3. package/dist/commands.d.ts +2 -4
  4. package/dist/commands.js +10 -3957
  5. package/dist/common/code.js +21 -0
  6. package/dist/common/constants.js +5 -0
  7. package/dist/common/env.js +33 -0
  8. package/dist/common/logger.d.ts +34 -0
  9. package/dist/common/logger.js +82 -0
  10. package/dist/common/logo.js +54 -0
  11. package/dist/common/progress-bar.js +167 -0
  12. package/dist/common/transformer.js +13 -0
  13. package/dist/common/types.d.ts +10 -0
  14. package/dist/config/compose-override.js +18 -0
  15. package/dist/config/defaults.d.ts +74 -0
  16. package/dist/config/defaults.js +74 -0
  17. package/dist/config/define-config.d.ts +13 -0
  18. package/dist/config/define-config.js +6 -0
  19. package/dist/config/index.d.ts +5 -0
  20. package/dist/config/index.js +5 -0
  21. package/dist/config/load-config.d.ts +19 -0
  22. package/dist/config/load-config.js +73 -0
  23. package/dist/config/merge-config.d.ts +12 -0
  24. package/dist/config/merge-config.js +20 -0
  25. package/dist/config/types.d.ts +452 -0
  26. package/dist/constants.d.ts +35 -0
  27. package/dist/constants.js +146 -0
  28. package/dist/core/assets.d.ts +91 -0
  29. package/dist/core/assets.js +244 -0
  30. package/dist/core/bundler.d.ts +15 -0
  31. package/dist/core/bundler.js +80 -0
  32. package/dist/core/env.d.ts +11 -0
  33. package/dist/core/env.js +36 -0
  34. package/dist/core/fs/data.js +9 -0
  35. package/dist/core/fs/storage.d.ts +15 -0
  36. package/dist/core/fs/storage.js +31 -0
  37. package/dist/core/plugins/babel-plugin.d.ts +22 -0
  38. package/dist/core/plugins/babel-plugin.js +74 -0
  39. package/dist/core/plugins/context.d.ts +10 -0
  40. package/dist/core/plugins/context.js +24 -0
  41. package/dist/core/plugins/dev-server-plugin.d.ts +13 -0
  42. package/dist/core/plugins/dev-server-plugin.js +27 -0
  43. package/dist/core/plugins/index.d.ts +13 -0
  44. package/dist/core/plugins/index.js +18 -0
  45. package/dist/core/plugins/prelude-plugin.d.ts +10 -0
  46. package/dist/core/plugins/prelude-plugin.js +23 -0
  47. package/dist/core/plugins/react-native-plugin.d.ts +36 -0
  48. package/dist/core/plugins/react-native-plugin.js +81 -0
  49. package/dist/core/plugins/reporter-plugin.d.ts +11 -0
  50. package/dist/core/plugins/reporter-plugin.js +87 -0
  51. package/dist/core/plugins/shared/filters.js +5 -0
  52. package/dist/core/plugins/swc-plugin.d.ts +26 -0
  53. package/dist/core/plugins/swc-plugin.js +108 -0
  54. package/dist/core/plugins/types.d.ts +18 -0
  55. package/dist/core/plugins/utils/source.js +10 -0
  56. package/dist/core/plugins/utils/transform-utils.js +56 -0
  57. package/dist/core/rolldown.js +313 -0
  58. package/dist/core/settings.js +19 -0
  59. package/dist/core/types.d.ts +83 -0
  60. package/dist/filter.d.ts +1 -0
  61. package/dist/filter.js +2 -0
  62. package/dist/hmr-runtime.iife.js +5 -5
  63. package/dist/index.d.ts +24 -1221
  64. package/dist/index.js +19 -4029
  65. package/dist/internal/react-native.js +24 -0
  66. package/dist/logger.js +5 -0
  67. package/dist/node/cli-utils.d.ts +10 -0
  68. package/dist/node/cli-utils.js +28 -0
  69. package/dist/node/cli.d.ts +6 -0
  70. package/dist/node/cli.js +23 -0
  71. package/dist/node/commands/agent/action.js +91 -0
  72. package/dist/node/commands/agent/command.js +10 -0
  73. package/dist/node/commands/agent/index.js +2 -0
  74. package/dist/node/commands/bundle/action.js +33 -0
  75. package/dist/node/commands/bundle/command.js +96 -0
  76. package/dist/node/commands/bundle/index.js +2 -0
  77. package/dist/node/commands/start/action.js +37 -0
  78. package/dist/node/commands/start/command.js +93 -0
  79. package/dist/node/commands/start/debugger.js +79 -0
  80. package/dist/node/commands/start/index.js +2 -0
  81. package/dist/node/commands/start/setup-interactive-mode.d.ts +20 -0
  82. package/dist/node/commands/start/setup-interactive-mode.js +107 -0
  83. package/dist/node/constants.js +4 -0
  84. package/dist/node/logger.js +5 -0
  85. package/dist/node/types.d.ts +23 -0
  86. package/dist/node/utils.js +23 -0
  87. package/dist/package.js +4 -0
  88. package/dist/runtime.js +1 -1
  89. package/dist/server/bundle.d.ts +12 -0
  90. package/dist/server/bundle.js +55 -0
  91. package/dist/server/bundler-pool.d.ts +51 -0
  92. package/dist/server/bundler-pool.js +197 -0
  93. package/dist/server/common/schema.js +19 -0
  94. package/dist/server/constants.d.ts +6 -0
  95. package/dist/server/constants.js +6 -0
  96. package/dist/server/create-dev-server.d.ts +6 -0
  97. package/dist/server/create-dev-server.js +185 -0
  98. package/dist/server/error.js +9 -0
  99. package/dist/server/events/event-bus.d.ts +12 -0
  100. package/dist/server/events/event-bus.js +16 -0
  101. package/dist/server/events/types.d.ts +37 -0
  102. package/dist/server/events/types.js +6 -0
  103. package/dist/server/index.d.ts +3 -0
  104. package/dist/server/index.js +3 -0
  105. package/dist/server/logger.js +33 -0
  106. package/dist/server/mcp/context.js +14 -0
  107. package/dist/server/mcp/server.js +86 -0
  108. package/dist/server/mcp/tools/app-log-diagnostics.js +37 -0
  109. package/dist/server/mcp/tools/build-diagnostics.js +97 -0
  110. package/dist/server/mcp/tools/build-info.js +33 -0
  111. package/dist/server/mcp/tools/device-diagnostics.js +52 -0
  112. package/dist/server/mcp/tools/index.js +277 -0
  113. package/dist/server/middlewares/request-logger.js +15 -0
  114. package/dist/server/middlewares/serve-assets.js +49 -0
  115. package/dist/server/middlewares/serve-bundle.js +72 -0
  116. package/dist/server/middlewares/sse.js +34 -0
  117. package/dist/server/middlewares/symbolicate.js +71 -0
  118. package/dist/server/sse/adapter.js +74 -0
  119. package/dist/server/sse/event-bus.js +26 -0
  120. package/dist/server/symbolicate.js +93 -0
  121. package/dist/server/types.d.ts +125 -0
  122. package/dist/server/wss/hmr-server.js +209 -0
  123. package/dist/server/wss/server.d.ts +9 -0
  124. package/dist/server/wss/server.js +70 -0
  125. package/dist/{runtime.d.cts → types/hmr.d.ts} +1 -12
  126. package/dist/types.d.ts +78 -0
  127. package/dist/utils/babel.js +11 -0
  128. package/dist/utils/build-options.js +17 -0
  129. package/dist/utils/bundle.js +6 -0
  130. package/dist/utils/config.d.ts +5 -0
  131. package/dist/utils/config.js +32 -0
  132. package/dist/utils/dev-server.js +51 -0
  133. package/dist/utils/env.js +7 -0
  134. package/dist/utils/errors.js +9 -0
  135. package/dist/utils/hash.js +8 -0
  136. package/dist/utils/id.js +28 -0
  137. package/dist/utils/node-resolve.js +42 -0
  138. package/dist/utils/promise.js +15 -0
  139. package/dist/utils/reporters.js +120 -0
  140. package/dist/utils/reset-cache.d.ts +8 -0
  141. package/dist/utils/reset-cache.js +25 -0
  142. package/dist/utils/response.js +91 -0
  143. package/dist/utils/run-build.d.ts +8 -0
  144. package/dist/utils/run-build.js +7 -0
  145. package/dist/utils/run-server.d.ts +6 -0
  146. package/dist/utils/run-server.js +20 -0
  147. package/dist/utils/runtime-target.js +9 -0
  148. package/dist/utils/serialize.js +10 -0
  149. package/dist/utils/server.js +6 -0
  150. package/dist/utils/storage.js +6 -0
  151. package/dist/utils/string.js +6 -0
  152. package/dist/utils/swc.js +10 -0
  153. package/dist/utils/terminal.js +86 -0
  154. package/dist/utils/url.js +23 -0
  155. package/package.json +56 -68
  156. package/dist/commands.cjs +0 -4008
  157. package/dist/commands.d.cts +0 -5
  158. package/dist/pluginutils.d.ts +0 -1
  159. package/dist/pluginutils.js +0 -2
  160. package/dist/runtime.cjs +0 -34
  161. /package/dist/{chunk-DXpK5_cz.js → chunk-DJV587Yu.js} +0 -0
@@ -0,0 +1,22 @@
1
+ import { BundlerContext } from "../types.js";
2
+ import { TransformerConfig } from "../../config/types.js";
3
+ import * as rolldown from "@rollipop/rolldown";
4
+
5
+ //#region src/core/plugins/babel-plugin.d.ts
6
+ interface BabelPluginOptions {
7
+ context: BundlerContext;
8
+ /**
9
+ * When `false`, the legacy JS preset (TS strip / Flow strip / RN
10
+ * codegen) is applied. When `true`, the preset is skipped and only
11
+ * user-provided rules run — the rust-side pipeline handles the rest.
12
+ */
13
+ useNativeTransformPipeline: boolean;
14
+ transformConfig?: TransformerConfig['babel'];
15
+ }
16
+ declare function babelPlugin({
17
+ context,
18
+ useNativeTransformPipeline,
19
+ transformConfig
20
+ }: BabelPluginOptions): rolldown.Plugin[];
21
+ //#endregion
22
+ export { BabelPluginOptions, babelPlugin };
@@ -0,0 +1,74 @@
1
+ import { __require } from "../../_virtual/_rolldown/runtime.js";
2
+ import { getFlag } from "./utils/transform-utils.js";
3
+ import { mergeBabelOptions } from "../../utils/babel.js";
4
+ import { isJSX, isTS } from "./utils/source.js";
5
+ import { invariant } from "es-toolkit";
6
+ import * as babel from "@babel/core";
7
+ //#region src/core/plugins/babel-plugin.ts
8
+ function babelPlugin({ context, useNativeTransformPipeline, transformConfig }) {
9
+ const { rules = [] } = transformConfig ?? {};
10
+ const babelOptionsById = /* @__PURE__ */ new Map();
11
+ const babelRules = rules.map(({ filter, options }, index) => {
12
+ return {
13
+ name: `rollipop:babel-rule-${index}`,
14
+ transform: {
15
+ filter,
16
+ handler(code, id) {
17
+ const existingBabelOptions = babelOptionsById.get(id);
18
+ const resolvedOptions = typeof options === "function" ? options(code, id) : options;
19
+ existingBabelOptions ? existingBabelOptions.push(resolvedOptions) : babelOptionsById.set(id, [resolvedOptions]);
20
+ }
21
+ }
22
+ };
23
+ });
24
+ const babelPlugin = {
25
+ name: "rollipop:babel",
26
+ buildStart() {
27
+ babelOptionsById.clear();
28
+ },
29
+ transform: { handler(code, id) {
30
+ const flags = getFlag.call(this, context, id);
31
+ if (flags & 128) return;
32
+ const babelOptions = babelOptionsById.get(id) ?? [];
33
+ if (!(useNativeTransformPipeline ? babelOptions.length > 0 : flags & 1 || babelOptions.length > 0)) return;
34
+ const baseOptions = useNativeTransformPipeline ? [] : [getPreset(flags, id)];
35
+ const result = babel.transformSync(code, {
36
+ filename: id,
37
+ babelrc: false,
38
+ configFile: false,
39
+ sourceMaps: true,
40
+ ...mergeBabelOptions([...baseOptions, ...babelOptions])
41
+ });
42
+ invariant(result?.code, `Failed to transform with babel: ${id}`);
43
+ return {
44
+ code: result.code,
45
+ map: result.map
46
+ };
47
+ } }
48
+ };
49
+ return [...babelRules, babelPlugin];
50
+ }
51
+ function getPreset(flags, id) {
52
+ const presets = [];
53
+ const plugins = [];
54
+ let parserOpts = null;
55
+ if (flags & 2) {
56
+ parserOpts = { flow: "all" };
57
+ plugins.push([__require.resolve("babel-plugin-syntax-hermes-parser"), {
58
+ parseLangTypes: "flow",
59
+ reactRuntimeTarget: "19"
60
+ }], __require.resolve("@babel/plugin-transform-flow-strip-types"));
61
+ } else if (isTS(id)) plugins.push([__require.resolve("@babel/plugin-transform-typescript"), {
62
+ isTSX: isJSX(id),
63
+ allowNamespaces: true
64
+ }]);
65
+ if (flags & 1) plugins.push([__require.resolve("@react-native/babel-plugin-codegen")]);
66
+ const options = {
67
+ presets,
68
+ plugins
69
+ };
70
+ if (parserOpts) options.parserOpts = parserOpts;
71
+ return options;
72
+ }
73
+ //#endregion
74
+ export { babelPlugin };
@@ -0,0 +1,10 @@
1
+ import { RollupLogWithString } from "@rollipop/rolldown";
2
+
3
+ //#region src/core/plugins/context.d.ts
4
+ interface PluginContext {
5
+ debug: (log: RollupLogWithString) => void;
6
+ info: (log: RollupLogWithString) => void;
7
+ warn: (log: RollupLogWithString) => void;
8
+ }
9
+ //#endregion
10
+ export { PluginContext };
@@ -0,0 +1,24 @@
1
+ import { Logger } from "../../common/logger.js";
2
+ import chalk from "chalk";
3
+ //#region src/core/plugins/context.ts
4
+ const pluginLogger = new Logger();
5
+ function createPluginContext(name) {
6
+ return {
7
+ debug: (log) => {
8
+ printPluginLog("debug", log, name);
9
+ },
10
+ info: (log) => {
11
+ printPluginLog("info", log, name);
12
+ },
13
+ warn: (log) => {
14
+ printPluginLog("warn", log, name);
15
+ }
16
+ };
17
+ }
18
+ function printPluginLog(level, log, pluginName = "unknown") {
19
+ const pluginLabel = chalk.magenta(`plugin:${pluginName}`);
20
+ if (typeof log === "string") pluginLogger[level](pluginLabel, log);
21
+ else pluginLogger[level](pluginLabel, log.stack ?? log.message);
22
+ }
23
+ //#endregion
24
+ export { createPluginContext, printPluginLog };
@@ -0,0 +1,13 @@
1
+ import { ResolvedConfig } from "../../config/defaults.js";
2
+ import { ResolvedHmrConfig } from "../../utils/config.js";
3
+ import * as rolldown from "@rollipop/rolldown";
4
+
5
+ //#region src/core/plugins/dev-server-plugin.d.ts
6
+ interface DevServerPluginOptions {
7
+ cwd: string;
8
+ hmrClientPath: ResolvedConfig['reactNative']['hmrClientPath'];
9
+ hmrConfig: ResolvedHmrConfig | null;
10
+ }
11
+ declare function devServerPlugin(options: DevServerPluginOptions): Promise<rolldown.Plugin[] | null>;
12
+ //#endregion
13
+ export { DevServerPluginOptions, devServerPlugin };
@@ -0,0 +1,27 @@
1
+ import { resolveFrom } from "../../utils/node-resolve.js";
2
+ import { rollipopReactRefreshWrapperPlugin } from "@rollipop/rolldown/experimental";
3
+ import { exactRegex, id, include } from "@rollipop/rolldown/filter";
4
+ //#region src/core/plugins/dev-server-plugin.ts
5
+ async function devServerPlugin(options) {
6
+ const { cwd, hmrClientPath, hmrConfig } = options;
7
+ if (hmrConfig == null) return null;
8
+ return [{
9
+ name: "rollipop:replace-hmr-client",
10
+ load: {
11
+ filter: [include(id(exactRegex(resolveFrom(cwd, typeof hmrClientPath === "function" ? await hmrClientPath(cwd) : hmrClientPath))))],
12
+ handler(id) {
13
+ this.debug(`Replacing HMR client: ${id}`);
14
+ return {
15
+ code: hmrConfig.clientImplement,
16
+ moduleType: "ts"
17
+ };
18
+ }
19
+ }
20
+ }, rollipopReactRefreshWrapperPlugin({
21
+ cwd,
22
+ include: [/\.[tj]sx?(?:$|\?)/],
23
+ exclude: [/\/node_modules\//]
24
+ })];
25
+ }
26
+ //#endregion
27
+ export { devServerPlugin };
@@ -0,0 +1,13 @@
1
+ import { ReactNativePluginOptions, reactNativePlugin } from "./react-native-plugin.js";
2
+ import { PreludePluginOptions, preludePlugin } from "./prelude-plugin.js";
3
+ import { BabelPluginOptions, babelPlugin } from "./babel-plugin.js";
4
+ import { SwcPluginOptions, swcPlugin } from "./swc-plugin.js";
5
+ import { ReporterPluginOptions, reporterPlugin } from "./reporter-plugin.js";
6
+ import { DevServerPluginOptions, devServerPlugin } from "./dev-server-plugin.js";
7
+
8
+ //#region src/core/plugins/index.d.ts
9
+ declare namespace index_d_exports {
10
+ export { BabelPluginOptions, DevServerPluginOptions, PreludePluginOptions, ReactNativePluginOptions, ReporterPluginOptions, SwcPluginOptions, babelPlugin as babel, devServerPlugin as devServer, preludePlugin as prelude, reactNativePlugin as reactNative, reporterPlugin as reporter, swcPlugin as swc };
11
+ }
12
+ //#endregion
13
+ export { index_d_exports };
@@ -0,0 +1,18 @@
1
+ import { __exportAll } from "../../_virtual/_rolldown/runtime.js";
2
+ import { reactNativePlugin } from "./react-native-plugin.js";
3
+ import { preludePlugin } from "./prelude-plugin.js";
4
+ import { babelPlugin } from "./babel-plugin.js";
5
+ import { swcPlugin } from "./swc-plugin.js";
6
+ import { reporterPlugin } from "./reporter-plugin.js";
7
+ import { devServerPlugin } from "./dev-server-plugin.js";
8
+ //#region src/core/plugins/index.ts
9
+ var plugins_exports = /* @__PURE__ */ __exportAll({
10
+ babel: () => babelPlugin,
11
+ devServer: () => devServerPlugin,
12
+ prelude: () => preludePlugin,
13
+ reactNative: () => reactNativePlugin,
14
+ reporter: () => reporterPlugin,
15
+ swc: () => swcPlugin
16
+ });
17
+ //#endregion
18
+ export { plugins_exports };
@@ -0,0 +1,10 @@
1
+ import * as rolldown from "@rollipop/rolldown";
2
+
3
+ //#region src/core/plugins/prelude-plugin.d.ts
4
+ interface PreludePluginOptions {
5
+ entryPath: string;
6
+ modulePaths: string[];
7
+ }
8
+ declare function preludePlugin(options: PreludePluginOptions): rolldown.Plugin | null;
9
+ //#endregion
10
+ export { PreludePluginOptions, preludePlugin };
@@ -0,0 +1,23 @@
1
+ import { invariant } from "es-toolkit";
2
+ import { id, include } from "@rollipop/rolldown/filter";
3
+ //#region src/core/plugins/prelude-plugin.ts
4
+ function preludePlugin(options) {
5
+ const { entryPath, modulePaths } = options;
6
+ if (modulePaths.length === 0) return null;
7
+ const importStatements = modulePaths.map((modulePath) => `import '${modulePath}';`).join("\n");
8
+ return {
9
+ name: "rollipop:prelude",
10
+ transform: {
11
+ order: "pre",
12
+ filter: [include(id(entryPath))],
13
+ handler(_code, _id, meta) {
14
+ const { magicString } = meta;
15
+ invariant(magicString, "magicString not found");
16
+ magicString.prepend(`${importStatements}\n`);
17
+ return { code: magicString };
18
+ }
19
+ }
20
+ };
21
+ }
22
+ //#endregion
23
+ export { preludePlugin };
@@ -0,0 +1,36 @@
1
+ import { BuildType, BundlerContext } from "../types.js";
2
+ import * as rolldown from "@rollipop/rolldown";
3
+ import { RollipopReactNativePluginConfig } from "@rollipop/rolldown/experimental";
4
+ import { TopLevelFilterExpression } from "@rollipop/rolldown/filter";
5
+
6
+ //#region src/core/plugins/react-native-plugin.d.ts
7
+ interface ReactNativePluginOptions {
8
+ context: BundlerContext;
9
+ projectRoot: string;
10
+ platform: string;
11
+ preferNativePlatform: boolean;
12
+ buildType: BuildType;
13
+ assetsDir?: string;
14
+ assetExtensions: string[];
15
+ assetRegistryPath: string;
16
+ /**
17
+ * Native pipeline configuration. When `null`, the legacy JS plugins
18
+ * (codegen marker + Flow strip) are installed instead.
19
+ *
20
+ * @internal builtin plugin config
21
+ */
22
+ builtinPluginConfig: RollipopReactNativePluginConfig | null;
23
+ /**
24
+ * Filter for the legacy Flow-strip transform pipeline. Used when the
25
+ * native pipeline is disabled.
26
+ */
27
+ flowFilter: rolldown.HookFilter | TopLevelFilterExpression[];
28
+ /**
29
+ * Filter for the legacy codegen marker pipeline. Used when the native
30
+ * pipeline is disabled.
31
+ */
32
+ codegenFilter: rolldown.HookFilter | TopLevelFilterExpression[];
33
+ }
34
+ declare function reactNativePlugin(options: ReactNativePluginOptions): rolldown.Plugin[];
35
+ //#endregion
36
+ export { ReactNativePluginOptions, reactNativePlugin };
@@ -0,0 +1,81 @@
1
+ import { stripFlowTypes } from "../../common/transformer.js";
2
+ import { copyAssetsToDestination, generateAssetRegistryCode, resolveScaledAssets } from "../assets.js";
3
+ import { getFlag, setFlag } from "./utils/transform-utils.js";
4
+ import { rollipopReactNativePlugin } from "@rollipop/rolldown/experimental";
5
+ import { id, include } from "@rollipop/rolldown/filter";
6
+ //#region src/core/plugins/react-native-plugin.ts
7
+ function reactNativePlugin(options) {
8
+ const { projectRoot, platform, preferNativePlatform, buildType, context, assetsDir, assetExtensions, assetRegistryPath, flowFilter, codegenFilter, builtinPluginConfig } = options;
9
+ const codegenPlugin = {
10
+ name: "rollipop:react-native-codegen-marker",
11
+ transform: {
12
+ order: "pre",
13
+ filter: codegenFilter,
14
+ handler(_code, id) {
15
+ return { meta: setFlag.call(this, context, id, 1) };
16
+ }
17
+ }
18
+ };
19
+ const stripFlowSyntaxPlugin = {
20
+ name: "rollipop:react-native-strip-flow-syntax",
21
+ transform: {
22
+ order: "pre",
23
+ filter: flowFilter,
24
+ async handler(code, id) {
25
+ const flags = getFlag.call(this, context, id);
26
+ if (flags & 128) return;
27
+ if (flags & 1) return { meta: setFlag.call(this, context, id, 2) };
28
+ const result = await stripFlowTypes(id, code);
29
+ return {
30
+ code: result.code,
31
+ map: result.map,
32
+ /**
33
+ * Treat the transformed code as TSX code
34
+ * because Flow modules can be `.js` files with type annotations and JSX syntax.
35
+ */
36
+ moduleType: "tsx"
37
+ };
38
+ }
39
+ }
40
+ };
41
+ const assets = [];
42
+ const assetPlugin = {
43
+ name: "rollipop:react-native-asset",
44
+ load: {
45
+ filter: [include(id(new RegExp(`\\.(?:${assetExtensions.join("|")})$`)))],
46
+ async handler(id) {
47
+ this.debug(`Asset ${id} found`);
48
+ const assetData = await resolveScaledAssets({
49
+ projectRoot,
50
+ assetPath: id,
51
+ platform,
52
+ preferNativePlatform
53
+ });
54
+ assets.push(assetData);
55
+ return {
56
+ code: generateAssetRegistryCode(assetRegistryPath, assetData),
57
+ meta: setFlag.call(this, context, id, 128),
58
+ moduleType: "js"
59
+ };
60
+ }
61
+ },
62
+ buildStart() {
63
+ assets.length = 0;
64
+ },
65
+ async buildEnd(error) {
66
+ if (error || buildType === "serve") return;
67
+ if (assetsDir != null) {
68
+ this.debug(`Copying assets to ${assetsDir}`);
69
+ await copyAssetsToDestination({
70
+ assets,
71
+ assetsDir,
72
+ platform,
73
+ preferNativePlatform
74
+ });
75
+ }
76
+ }
77
+ };
78
+ return [...builtinPluginConfig ? [rollipopReactNativePlugin(builtinPluginConfig)] : [codegenPlugin, stripFlowSyntaxPlugin], assetPlugin];
79
+ }
80
+ //#endregion
81
+ export { reactNativePlugin };
@@ -0,0 +1,11 @@
1
+ import { Reporter } from "../../types.js";
2
+ import * as rolldown from "@rollipop/rolldown";
3
+
4
+ //#region src/core/plugins/reporter-plugin.d.ts
5
+ interface ReporterPluginOptions {
6
+ initialTotalModules?: number;
7
+ reporter?: Reporter;
8
+ }
9
+ declare function reporterPlugin(options?: ReporterPluginOptions): rolldown.Plugin | null;
10
+ //#endregion
11
+ export { ReporterPluginOptions, reporterPlugin };
@@ -0,0 +1,87 @@
1
+ //#region src/core/plugins/reporter-plugin.ts
2
+ function reporterPlugin(options) {
3
+ const { reporter, initialTotalModules = 0 } = options ?? {};
4
+ let lastBuildTotalModules = initialTotalModules;
5
+ let totalModules = initialTotalModules;
6
+ let startedAt = 0;
7
+ let transformedModules = 0;
8
+ let cacheHitModules = 0;
9
+ let unknownTotalModules = totalModules === 0;
10
+ let countCacheHitModules = true;
11
+ function getProcessedModules() {
12
+ return transformedModules + cacheHitModules;
13
+ }
14
+ function resetIncrementalProgress() {
15
+ startedAt = performance.now();
16
+ transformedModules = 0;
17
+ cacheHitModules = 0;
18
+ totalModules = 0;
19
+ unknownTotalModules = false;
20
+ countCacheHitModules = false;
21
+ }
22
+ function resetBuildProgress() {
23
+ startedAt = performance.now();
24
+ transformedModules = 0;
25
+ cacheHitModules = 0;
26
+ totalModules = lastBuildTotalModules;
27
+ unknownTotalModules = totalModules === 0;
28
+ countCacheHitModules = true;
29
+ }
30
+ function reportProgress(id) {
31
+ const processedModules = getProcessedModules();
32
+ if (!unknownTotalModules && totalModules < processedModules) totalModules = processedModules;
33
+ reporter?.update({
34
+ type: "transform",
35
+ id,
36
+ totalModules: unknownTotalModules ? void 0 : totalModules,
37
+ transformedModules: processedModules
38
+ });
39
+ }
40
+ return {
41
+ name: "rollipop:status",
42
+ buildStart() {
43
+ resetBuildProgress();
44
+ reporter?.update({ type: "bundle_build_started" });
45
+ },
46
+ buildEnd(error) {
47
+ const endedAt = performance.now();
48
+ const processedModules = getProcessedModules();
49
+ if (processedModules !== 0) {
50
+ totalModules = processedModules;
51
+ lastBuildTotalModules = processedModules;
52
+ }
53
+ unknownTotalModules = false;
54
+ reporter?.update(error == null ? {
55
+ type: "bundle_build_done",
56
+ totalModules,
57
+ transformedModules,
58
+ cacheHitModules,
59
+ duration: endedAt - startedAt
60
+ } : {
61
+ type: "bundle_build_failed",
62
+ error
63
+ });
64
+ },
65
+ transform: {
66
+ order: "post",
67
+ handler(_code, id) {
68
+ ++transformedModules;
69
+ reportProgress(id);
70
+ }
71
+ },
72
+ transformCacheHit(id) {
73
+ if (!countCacheHitModules) return;
74
+ ++cacheHitModules;
75
+ reportProgress(id);
76
+ },
77
+ watchChange(id) {
78
+ resetIncrementalProgress();
79
+ reporter?.update({
80
+ type: "watch_change",
81
+ id
82
+ });
83
+ }
84
+ };
85
+ }
86
+ //#endregion
87
+ export { reporterPlugin };
@@ -0,0 +1,5 @@
1
+ import { exclude, id, or } from "@rollipop/rolldown/filter";
2
+ //#region src/core/plugins/shared/filters.ts
3
+ const ROLLDOWN_RUNTIME_EXCLUDE_FILTER = exclude(or(id(/rolldown\/runtime/), id(/@oxc-project\+runtime/)));
4
+ //#endregion
5
+ export { ROLLDOWN_RUNTIME_EXCLUDE_FILTER };
@@ -0,0 +1,26 @@
1
+ import { BundlerContext } from "../types.js";
2
+ import { TransformerConfig } from "../../config/types.js";
3
+ import { ResolvedConfig } from "../../config/defaults.js";
4
+ import * as rolldown from "@rollipop/rolldown";
5
+
6
+ //#region src/core/plugins/swc-plugin.d.ts
7
+ interface SwcPluginOptions {
8
+ context: BundlerContext;
9
+ /**
10
+ * When `false`, the legacy JS preset for the resolved `runtimeTarget`
11
+ * is applied to every module (TS/JSX strip, hermes target). When
12
+ * `true`, the preset is skipped and only user-provided rules run — the
13
+ * rust-side pipeline handles the rest.
14
+ */
15
+ useNativeTransformPipeline: boolean;
16
+ runtimeTarget: ResolvedConfig['runtimeTarget'];
17
+ transformConfig?: TransformerConfig['swc'];
18
+ }
19
+ declare function swcPlugin({
20
+ context,
21
+ useNativeTransformPipeline,
22
+ runtimeTarget,
23
+ transformConfig
24
+ }: SwcPluginOptions): rolldown.Plugin[];
25
+ //#endregion
26
+ export { SwcPluginOptions, swcPlugin };
@@ -0,0 +1,108 @@
1
+ import { getFlag } from "./utils/transform-utils.js";
2
+ import { mergeSwcOptions } from "../../utils/swc.js";
3
+ import { ROLLDOWN_RUNTIME_EXCLUDE_FILTER } from "./shared/filters.js";
4
+ import { id, include } from "@rollipop/rolldown/filter";
5
+ import * as swc from "@swc/core";
6
+ //#region src/core/plugins/swc-plugin.ts
7
+ function swcPlugin({ context, useNativeTransformPipeline, runtimeTarget, transformConfig }) {
8
+ const { rules = [] } = transformConfig ?? {};
9
+ const swcOptionsById = /* @__PURE__ */ new Map();
10
+ const swcHelpersResolvePlugin = {
11
+ name: "rollipop:swc-helpers-resolve",
12
+ resolveId: {
13
+ order: "pre",
14
+ filter: [include(id(/^@swc\/helpers/)), ROLLDOWN_RUNTIME_EXCLUDE_FILTER],
15
+ handler(source, _importer, extraOptions) {
16
+ return this.resolve(source, import.meta.dirname, extraOptions);
17
+ }
18
+ }
19
+ };
20
+ const swcRules = rules.map(({ filter, options }, index) => {
21
+ return {
22
+ name: `rollipop:swc-rule-${index}`,
23
+ transform: {
24
+ filter,
25
+ handler(code, id) {
26
+ const existingBabelOptions = swcOptionsById.get(id);
27
+ const resolvedOptions = typeof options === "function" ? options(code, id) : options;
28
+ existingBabelOptions ? existingBabelOptions.push(resolvedOptions) : swcOptionsById.set(id, [resolvedOptions]);
29
+ }
30
+ }
31
+ };
32
+ });
33
+ const getSwcPreset = useNativeTransformPipeline ? null : presets[runtimeTarget];
34
+ const swcPlugin = {
35
+ name: "rollipop:swc",
36
+ buildStart() {
37
+ swcOptionsById.clear();
38
+ },
39
+ transform: {
40
+ filter: [ROLLDOWN_RUNTIME_EXCLUDE_FILTER],
41
+ handler(code, id) {
42
+ if (getFlag.call(this, context, id) & 128) return;
43
+ const swcOptions = swcOptionsById.get(id) ?? [];
44
+ if (getSwcPreset == null && swcOptions.length === 0) return;
45
+ const baseOptions = getSwcPreset != null ? [getSwcPreset(id)] : [];
46
+ const result = swc.transformSync(code, {
47
+ filename: id,
48
+ configFile: false,
49
+ swcrc: false,
50
+ sourceMaps: true,
51
+ inputSourceMap: false,
52
+ ...mergeSwcOptions([...baseOptions, ...swcOptions])
53
+ });
54
+ return {
55
+ code: result.code,
56
+ map: result.map
57
+ };
58
+ }
59
+ }
60
+ };
61
+ return [
62
+ swcHelpersResolvePlugin,
63
+ ...swcRules,
64
+ swcPlugin
65
+ ];
66
+ }
67
+ const presets = {
68
+ "hermes-v1": (id) => ({
69
+ env: {
70
+ targets: { node: 9999 },
71
+ include: [
72
+ "transform-block-scoping",
73
+ "transform-class-properties",
74
+ "transform-private-methods",
75
+ "transform-private-property-in-object"
76
+ ]
77
+ },
78
+ jsc: {
79
+ parser: {
80
+ syntax: "typescript",
81
+ tsx: true
82
+ },
83
+ transform: { react: { runtime: "preserve" } },
84
+ externalHelpers: true
85
+ },
86
+ isModule: id.endsWith(".cjs") ? "commonjs" : true
87
+ }),
88
+ hermes: (id) => ({
89
+ jsc: {
90
+ parser: {
91
+ syntax: "typescript",
92
+ tsx: true
93
+ },
94
+ transform: { react: { runtime: "preserve" } },
95
+ externalHelpers: true,
96
+ keepClassNames: true,
97
+ loose: false,
98
+ assumptions: {
99
+ setPublicClassFields: true,
100
+ privateFieldsAsProperties: true
101
+ },
102
+ target: "es5"
103
+ },
104
+ isModule: id.endsWith(".cjs") ? "commonjs" : true
105
+ })
106
+ };
107
+ //#endregion
108
+ export { swcPlugin };
@@ -0,0 +1,18 @@
1
+ import { AsyncResult } from "../types.js";
2
+ import { DevServer } from "../../server/types.js";
3
+ import { PluginContext } from "./context.js";
4
+ import { Config } from "../../config/types.js";
5
+ import { ResolvedConfig } from "../../config/defaults.js";
6
+ import * as rolldown from "@rollipop/rolldown";
7
+
8
+ //#region src/core/plugins/types.d.ts
9
+ type PluginConfig = Omit<Config, 'plugins'>;
10
+ type ResolvedPluginConfig = Omit<ResolvedConfig, 'plugins'>;
11
+ type InternalRolldownHook = 'transformCacheHit';
12
+ type Plugin = Omit<rolldown.Plugin, InternalRolldownHook> & {
13
+ config?: PluginConfig | ((this: PluginContext, config: PluginConfig) => AsyncResult<PluginConfig | null | void>);
14
+ configResolved?: (this: PluginContext, config: ResolvedConfig) => AsyncResult<void>;
15
+ configureServer?: (this: PluginContext, server: DevServer) => AsyncResult<void | (() => AsyncResult<void>)>;
16
+ };
17
+ //#endregion
18
+ export { Plugin, PluginConfig, ResolvedPluginConfig };
@@ -0,0 +1,10 @@
1
+ //#region src/core/plugins/utils/source.ts
2
+ const TS_EXTENSION_REGEXP = /\.tsx?$/;
3
+ function isTS(id) {
4
+ return TS_EXTENSION_REGEXP.test(id);
5
+ }
6
+ function isJSX(id) {
7
+ return id.endsWith("x");
8
+ }
9
+ //#endregion
10
+ export { isJSX, isTS };