@codemoreira/esad 2.0.1-4 → 2.0.1-5

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/README.md CHANGED
@@ -1,82 +1,88 @@
1
- # ESAD (Easy Super App Development) šŸš€
2
-
3
- Zero-Config CLI and DevTools for React Native Module Federation + Expo.
4
-
5
- ESAD is a unified toolkit designed to abstract all the complexity from Super App development using **Re.Pack (Rspack)** and **Expo**.
6
-
7
- ---
8
-
9
- ## šŸ—ļø CLI Commands
10
-
11
- ### 1. Initialize a Workspace
12
- ```bash
13
- npx @codemoreira/esad init my-project
14
- ```
15
-
16
- ### 2. Create a Federated Module
17
- ```bash
18
- npx esad create-module module-name
19
- ```
20
-
21
- ### 3. Create a Local CDN / Registry
22
- ```bash
23
- npx esad create-cdn
24
- ```
25
-
26
- ### 4. Development & Native Automation
27
- Starts the Rspack server and **automatically patches** native files (Gradle, Entry Points) if necessary.
28
- ```bash
29
- npx esad host dev # Run the Host App
30
- npx esad dev --id module-name --port 9000 # Run a Module
31
- ```
32
-
33
- ### 5. Build for Production
34
- Prepares the bundle and chunks for deployment, generating a standardized `./build` directory.
35
- ```bash
36
- npx esad build --id module-name --platform android
37
- ```
38
-
39
- ### 6. Deployment
40
- Packages the `./build` folder and uploads it to your configured Registry/CDN via multipart POST.
41
- ```bash
42
- npx esad deploy --id module-name --version 1.0.0
43
- ```
44
-
45
- ---
46
-
47
- ## šŸ› ļø Library Usage
48
-
49
- ### šŸŽØ Bundler Plugin (`@codemoreira/esad/plugin`)
50
- Wrap your configuration to enable ESAD's smart resolution and redirection logic:
51
- ```javascript
52
- import { withESAD } from '@codemoreira/esad/plugin';
53
-
54
- export default withESAD({
55
- type: 'module', // or 'host'
56
- id: 'my-mini-app'
57
- });
58
- ```
59
-
60
- ### ⚔ Global State SDK (`@codemoreira/esad/client`)
61
- Share state across the Host and all Remote Modules reactively:
62
- ```javascript
63
- import { useESADState } from '@codemoreira/esad/client';
64
-
65
- const [user, setUser] = useESADState('user');
66
- ```
67
-
68
- ---
69
-
70
- ## šŸ  Template Features (Host & Module)
71
-
72
- ESAD provides high-quality, boilerplate-free templates:
73
- - **šŸš€ Rspack + Re.Pack**: Blazing fast builds powered by Rspack.
74
- - **šŸ“± Clean UI**: Modern, responsive designs built with **Vanilla StyleSheet** (No external CSS libraries required).
75
- - **šŸ›¤ļø Dynamic Navigation**: Pre-configured Dashboard and Module Viewer with **Suspense** support.
76
- - **šŸ” State-Driven Auth**: Built-in login and session management via the ESAD SDK.
77
- - **šŸ”§ Automated Patching**: CLI-driven injection of Re.Pack extensions into Android and iOS native projects.
78
-
79
- ---
80
-
81
- ## šŸŽØ Architecture & Workflow
82
- For technical diagrams and the modular deployment lifecycle, see [ESAD_ARCHITECTURE.md](./ESAD_ARCHITECTURE.md).
1
+ # ESAD (Easy Super App Development) šŸš€
2
+
3
+ Zero-Config CLI and DevTools for React Native Module Federation + Expo.
4
+
5
+ ESAD is a unified toolkit designed to abstract all the complexity from Super App development using **Re.Pack (Rspack)** and **Expo**. It provides a professional, linear workflow from scaffolding to deployment.
6
+
7
+ ---
8
+
9
+ ## šŸ—ļø CLI Workflow (V2)
10
+
11
+ ### 1. Initialize a Workspace
12
+ Creates the project root, a programmable `esad.config.js`, and the Host Application.
13
+ ```bash
14
+ npx @codemoreira/esad init my-project
15
+ ```
16
+
17
+ ### 2. Expand your Workspace
18
+ Create new Federated Modules or a Local Registry/CDN.
19
+ ```bash
20
+ esad create my-module # Creates a new module (Feature)
21
+ esad create --type cdn # Scaffolds a local registry for testing
22
+ ```
23
+
24
+ ### 3. Development Manager (Unified)
25
+ The `dev` command is the single entry point for development. It automatically detects if it should run the Host or a Module.
26
+
27
+ **Run the Host App (Interactive):**
28
+ ```bash
29
+ esad dev
30
+ ```
31
+ *Allows selecting Android, iOS, or Bundler Only. Automatically patches native files.*
32
+
33
+ **Run a specific Module:**
34
+ ```bash
35
+ esad dev my-module --port 9000
36
+ ```
37
+ *Starts the module server and updates the Host's local mapping automatically.*
38
+
39
+ ### 4. Build & Deploy
40
+ Prepare and push your features to the registry.
41
+
42
+ **Build for Production:**
43
+ ```bash
44
+ esad build my-module --platform android
45
+ ```
46
+
47
+ **Execute Programmable Deploy:**
48
+ ```bash
49
+ esad deploy my-module --version 1.0.0
50
+ ```
51
+
52
+ ---
53
+
54
+ ## šŸ› ļø Library Usage
55
+
56
+ ### šŸŽØ Bundler Plugin (`@codemoreira/esad/plugin`)
57
+ Wrap your configuration to enable ESAD's smart resolution and redirection logic:
58
+ ```javascript
59
+ import { withESAD } from '@codemoreira/esad/plugin';
60
+
61
+ export default withESAD({
62
+ type: 'module', // or 'host'
63
+ id: 'my-mini-app'
64
+ });
65
+ ```
66
+
67
+ ### ⚔ Global State SDK (`@codemoreira/esad/client`)
68
+ Share state across the Host and all Remote Modules reactively:
69
+ ```javascript
70
+ import { useESADState } from '@codemoreira/esad/client';
71
+
72
+ const [user, setUser] = useESADState('user');
73
+ ```
74
+
75
+ ---
76
+
77
+ ## šŸ  Template Features (Host & Module)
78
+ ESAD templates provide a high-end starting point:
79
+ - **šŸš€ Rspack + Re.Pack**: Blazing fast builds.
80
+ - **šŸ“± Professional Architecture**: Modular structure (`src/api`, `src/components`, `src/navigation`).
81
+ - **šŸ›¤ļø Dynamic Navigation**: Pre-configured Module Viewer with **Suspense** and **ErrorBoundary** support.
82
+ - **šŸ” State-Driven Auth**: Built-in login and session management via the ESAD SDK.
83
+ - **šŸ”§ Automated Native Patching**: Zero-config injection into Android/iOS projects.
84
+
85
+ ---
86
+
87
+ ## šŸŽØ Architecture & Workflow
88
+ For technical diagrams and the full lifecycle, see [ESAD_ARCHITECTURE.md](./ESAD_ARCHITECTURE.md).
package/bin/esad.js CHANGED
@@ -24,12 +24,13 @@ program
24
24
  await require('../src/cli/commands/create')(name, options);
25
25
  });
26
26
 
27
- // --- COMMAND: esad dev [moduleId] ---
27
+ // --- COMMAND: esad dev [id] ---
28
28
  program
29
- .command('dev [id]') // [id] as alias to -i for better UX
29
+ .command('dev [id]')
30
30
  .option('-i, --id <moduleId>', 'The Module ID to run in dev mode')
31
31
  .option('-p, --port <port>', 'The port to run the dev server on', '8081')
32
- .description('Starts the development environment for a module or the host application')
32
+ .option('--platform <platform>', 'Platform for host: android, ios, bundler')
33
+ .description('Starts the development environment. Run without [id] for Host App or with [id] for a specific Module.')
33
34
  .action(async (id, options) => {
34
35
  const opts = { ...options, id: id || options.id };
35
36
  await require('../src/cli/commands/dev')(opts);
@@ -40,7 +41,7 @@ program
40
41
  .command('build [id]')
41
42
  .option('-i, --id <moduleId>', 'The Module ID to build')
42
43
  .option('-p, --platform <platform>', 'Platform: android, ios', 'android')
43
- .description('Builds a production bundle')
44
+ .description('Builds a production bundle for a module or the host application')
44
45
  .action(async (id, options) => {
45
46
  const opts = { ...options, id: id || options.id };
46
47
  await require('../src/cli/commands/build')(opts);
@@ -57,14 +58,6 @@ program
57
58
  await require('../src/cli/commands/deploy')(opts);
58
59
  });
59
60
 
60
- // --- COMMAND: esad host <sub> ---
61
- program
62
- .command('host <subcommand>')
63
- .description('Manage host application (android, ios, login)')
64
- .action(async (sub) => {
65
- await require('../src/cli/commands/host')(sub);
66
- });
67
-
68
61
  // --- COMMAND: esad doctor ---
69
62
  program
70
63
  .command('doctor')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemoreira/esad",
3
- "version": "2.0.1-4",
3
+ "version": "2.0.1-5",
4
4
  "description": "Easy Super App Development - Zero-Config CLI and DevTools for React Native Module Federation",
5
5
  "main": "src/plugin/index.js",
6
6
  "types": "./src/plugin/index.d.ts",
@@ -22,25 +22,29 @@ const isPortInUse = (port) => new Promise((resolve) => {
22
22
  req.end();
23
23
  });
24
24
 
25
- const runHostDevFlow = async (cwd) => {
26
- const rl = readline.createInterface({
27
- input: process.stdin,
28
- output: process.stdout
29
- });
30
- const askQuestion = (query) => new Promise((resolve) => rl.question(query, resolve));
31
-
32
- console.log(`\n${chalk.bold('ESAD Host Dev Manager')}`);
33
- console.log(chalk.dim(`---------------------`));
34
- console.log(`[a] Run on Android`);
35
- console.log(`[i] Run on iOS`);
36
- console.log(`[b] Bundler Only`);
37
- console.log(`[c] Cancel`);
38
-
39
- const choice = (await askQuestion(`\nSelect platform: `)).toLowerCase();
25
+ const runHostDevFlow = async (cwd, options = {}) => {
26
+ let choice = options.platform ? options.platform.charAt(0).toLowerCase() : null;
27
+
28
+ if (!choice) {
29
+ const rl = readline.createInterface({
30
+ input: process.stdin,
31
+ output: process.stdout
32
+ });
33
+ const askQuestion = (query) => new Promise((resolve) => rl.question(query, resolve));
34
+
35
+ console.log(`\n${chalk.bold('ESAD Host Dev Manager')}`);
36
+ console.log(chalk.dim(`---------------------`));
37
+ console.log(`[a] Run on Android`);
38
+ console.log(`[i] Run on iOS`);
39
+ console.log(`[b] Bundler Only`);
40
+ console.log(`[c] Cancel`);
41
+
42
+ choice = (await askQuestion(`\nSelect platform: `)).toLowerCase();
43
+ rl.close();
44
+ }
40
45
 
41
46
  if (choice === 'c') {
42
47
  console.log(`\nāŒ Cancelled.`);
43
- rl.close();
44
48
  return;
45
49
  }
46
50
 
@@ -81,7 +85,6 @@ const runHostDevFlow = async (cwd) => {
81
85
 
82
86
  if (!(await waitForBundler())) {
83
87
  console.error(`\nāŒ Timeout: Bundler did not respond.`);
84
- rl.close();
85
88
  return;
86
89
  }
87
90
  console.log(`āœ… Bundler ready!`);
@@ -93,9 +96,9 @@ const runHostDevFlow = async (cwd) => {
93
96
  } else if (choice === 'i') {
94
97
  console.log(`šŸŽ Launching iOS...`);
95
98
  await runProcess('react-native', ['run-ios', '--no-packager'], cwd);
99
+ } else if (choice === 'b') {
100
+ console.log(`✨ Bundler is active.`);
96
101
  }
97
-
98
- rl.close();
99
102
  };
100
103
 
101
104
  module.exports = async (options) => {
@@ -164,7 +167,7 @@ module.exports = async (options) => {
164
167
 
165
168
  if (isHost) {
166
169
  await prepareNative(cwd, 'all');
167
- await runHostDevFlow(cwd);
170
+ await runHostDevFlow(cwd, options);
168
171
  } else {
169
172
  console.error(chalk.red(`āŒ Error: Could not detect Host or Module context.`));
170
173
  console.log(`šŸ‘‰ Try: esad dev <module-id>`);
@@ -75,7 +75,7 @@ export default {
75
75
  console.log(chalk.green(`\nšŸŽ‰ ESAD Workspace Initialized successfully!`));
76
76
  console.log(chalk.cyan(`\nšŸ‘‰ Next steps:`));
77
77
  console.log(` 1. cd ${projectName}/${hostName}`);
78
- console.log(` 2. esad host dev (to start Host)`);
78
+ console.log(` 2. esad dev (to start Host)`);
79
79
  console.log(` 3. esad dev (in a module folder to federate)\n`);
80
80
  } catch (err) {
81
81
  console.error(chalk.red(`\nāŒ Failed to initialize workspace:`));
@@ -59,7 +59,7 @@ function withESAD(env, options) {
59
59
  {
60
60
  test: /\.[cm]?[jt]sx?$/,
61
61
  include: [
62
- /node_modules[\\/](react-native|@react-native|expo|expo-modules-core|@expo|react-navigation|@react-navigation|@unimodules|unimodules|native-base)/,
62
+ /node_modules[\\/](react-native|@react-native|expo|expo-modules-core|@expo|react-navigation|@react-navigation|@unimodules|unimodules|native-base|react-native-screens|react-native-reanimated)/,
63
63
  ],
64
64
  type: 'javascript/auto',
65
65
  resolve: { fullySpecified: false },
@@ -67,10 +67,10 @@ function withESAD(env, options) {
67
67
  loader: 'babel-loader',
68
68
  options: {
69
69
  presets: [
70
- [
71
- 'babel-preset-expo',
72
- { native: { disableImportExportTransform: false } },
73
- ],
70
+ '@react-native/babel-preset',
71
+ ],
72
+ plugins: [
73
+ ['@babel/plugin-transform-react-jsx', { runtime: 'automatic' }],
74
74
  ],
75
75
  sourceType: 'unambiguous',
76
76
  caller: { name: 'repack' },
@@ -80,6 +80,7 @@ function withESAD(env, options) {
80
80
  {
81
81
  test: /\.[cm]?[jt]sx?$/,
82
82
  include: [dirname],
83
+ exclude: [/node_modules/],
83
84
  type: 'javascript/auto',
84
85
  use: {
85
86
  loader: 'babel-loader',
@@ -1,42 +0,0 @@
1
- const { runProcess } = require('../utils/process');
2
- const path = require('path');
3
- const fs = require('fs-extra');
4
- const { getWorkspaceConfig } = require('../utils/config');
5
-
6
- module.exports = async (subcommand) => {
7
- let cwd = process.cwd();
8
- let pkgPath = path.join(cwd, 'package.json');
9
-
10
- const configObj = getWorkspaceConfig();
11
- if (configObj) {
12
- const workspaceRoot = configObj.root;
13
- const { projectName } = configObj.data;
14
- const hostDir = path.join(workspaceRoot, `${projectName}-host`);
15
-
16
- if (fs.existsSync(hostDir)) {
17
- cwd = hostDir;
18
- pkgPath = path.join(cwd, 'package.json');
19
- }
20
- }
21
-
22
- if (!fs.existsSync(pkgPath)) {
23
- console.error(`āŒ Error: Call this command from inside the Host App or the Workspace Root.`);
24
- return;
25
- }
26
-
27
- // Handle direct platform commands
28
- try {
29
- if (subcommand === 'android') {
30
- console.log(`šŸ¤– Compiling and launching on Android...`);
31
- await runProcess('react-native', ['run-android', '--no-packager'], cwd);
32
- } else if (subcommand === 'ios') {
33
- console.log(`šŸŽ Compiling and launching on iOS...`);
34
- await runProcess('react-native', ['run-ios', '--no-packager'], cwd);
35
- } else {
36
- console.log(`\nšŸ’” Tip: Use 'esad dev' for the interactive dev manager.`);
37
- console.log(` Or use 'esad host android' / 'esad host ios' for direct runs.`);
38
- }
39
- } catch (err) {
40
- console.error(`āŒ Error running host command: ${err.message}`);
41
- }
42
- };