react-on-fly 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # 🦋 react-on-fly
1
+ # 🚀 react-on-fly
2
2
 
3
3
  **Preview your React components on the fly!**
4
4
 
@@ -17,11 +17,11 @@ npx react-on-fly <path-to-file> -p <port-number> -rv <react-version> -w <watch-c
17
17
  Using `bunx` (Bun):
18
18
 
19
19
  ```bash
20
- bunx react-on-fly <path-to-file> -p <port-number> -rv <react-version> -w <watch-changes-boolean>
20
+ bunx react-on-fly --bun <path-to-file> -p <port-number> -rv <react-version> -w <watch-changes-boolean>
21
21
  ```
22
22
 
23
23
  Using `dx` (Deno):
24
24
 
25
25
  ```bash
26
- dx react-on-fly <path-to-file> -p <port-number> -rv <react-version> -w <watch-changes-boolean>
26
+ deno x react-on-fly <path-to-file> -p <port-number> -rv <react-version> -w <watch-changes-boolean>
27
27
  ```
@@ -0,0 +1,6 @@
1
+ export declare function parseArgs(): {
2
+ inputFile: string;
3
+ PORT: number;
4
+ reactVersion: string;
5
+ watchMode: boolean;
6
+ };
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseArgs = parseArgs;
4
+ function parseArgs() {
5
+ const inputFile = process.argv[2];
6
+ if (!inputFile || inputFile.startsWith('-')) {
7
+ console.error('❌ Error: You must specify a file to compile as the first argument.');
8
+ console.log('💡 Usage: react-on-fly <file.js|jsx|ts|tsx> [-p <port>] [-rv <version>] [-w <boolean>]');
9
+ process.exit(1);
10
+ }
11
+ let PORT = 3000;
12
+ let reactVersion = 'latest';
13
+ let watchMode = false;
14
+ const args = process.argv.slice(3);
15
+ for (let i = 0; i < args.length; i++) {
16
+ const arg = args[i];
17
+ switch (arg) {
18
+ case '-p':
19
+ const parsedPort = parseInt(args[++i], 10);
20
+ if (!isNaN(parsedPort) && parsedPort > 0)
21
+ PORT = parsedPort;
22
+ break;
23
+ case '-rv':
24
+ reactVersion = args[++i] || 'latest';
25
+ break;
26
+ case '-w':
27
+ const nextArg = args[i + 1];
28
+ if (nextArg === 'true' || nextArg === 'false') {
29
+ watchMode = nextArg === 'true';
30
+ i++;
31
+ }
32
+ else
33
+ watchMode = true;
34
+ break;
35
+ }
36
+ }
37
+ return { inputFile, PORT, reactVersion, watchMode };
38
+ }
39
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/func/args.ts"],"names":[],"mappings":";;AAAA,8BAmCC;AAnCD,SAAgB,SAAS;IACrB,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAElC,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,OAAO,CAAC,KAAK,CAAC,oEAAoE,CAAC,CAAC;QACpF,OAAO,CAAC,GAAG,CAAC,wFAAwF,CAAC,CAAC;QACtG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,IAAI,YAAY,GAAG,QAAQ,CAAC;IAC5B,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,QAAQ,GAAG,EAAE,CAAC;YACV,KAAK,IAAI;gBACL,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC3C,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC;oBAAE,IAAI,GAAG,UAAU,CAAC;gBAC5D,MAAM;YACV,KAAK,KAAK;gBACN,YAAY,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,QAAQ,CAAC;gBACrC,MAAM;YACV,KAAK,IAAI;gBACL,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC5B,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;oBAC5C,SAAS,GAAG,OAAO,KAAK,MAAM,CAAC;oBAC/B,CAAC,EAAE,CAAC;gBACR,CAAC;;oBAAM,SAAS,GAAG,IAAI,CAAC;gBACxB,MAAM;QACd,CAAC;IACL,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AACxD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type BuildContext } from 'esbuild';
2
+ export declare function bundleCode(entryPath: string, bundlePath: string, tempDir: string, watchMode: boolean): Promise<BuildContext | undefined>;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.bundleCode = bundleCode;
7
+ const esbuild_1 = require("esbuild");
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ async function bundleCode(entryPath, bundlePath, tempDir, watchMode) {
10
+ const buildOptions = {
11
+ entryPoints: [entryPath],
12
+ bundle: true,
13
+ outfile: bundlePath,
14
+ format: 'iife',
15
+ loader: { '.js': 'jsx', '.ts': 'tsx', '.jsx': 'jsx', '.tsx': 'tsx' },
16
+ nodePaths: [node_path_1.default.join(tempDir, 'node_modules')]
17
+ };
18
+ let ctx;
19
+ if (!watchMode)
20
+ await (0, esbuild_1.build)(buildOptions);
21
+ else {
22
+ ctx = await (0, esbuild_1.context)(buildOptions);
23
+ await ctx.watch();
24
+ }
25
+ return ctx;
26
+ }
27
+ //# sourceMappingURL=bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/func/bundle.ts"],"names":[],"mappings":";;;;;AAIA,gCAmBC;AAvBD,qCAA+E;AAC/E,0DAA6B;AAGtB,KAAK,UAAU,UAAU,CAAC,SAAiB,EAAE,UAAkB,EAAE,OAAe,EAAE,SAAkB;IAEvG,MAAM,YAAY,GAAiB;QAC/B,WAAW,EAAE,CAAC,SAAS,CAAC;QACxB,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,UAAU;QACnB,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE;QACpE,SAAS,EAAE,CAAC,mBAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;KAClD,CAAC;IAEF,IAAI,GAA6B,CAAC;IAClC,IAAI,CAAC,SAAS;QAAE,MAAM,IAAA,eAAK,EAAC,YAAY,CAAC,CAAC;SACrC,CAAC;QACF,GAAG,GAAG,MAAM,IAAA,iBAAO,EAAC,YAAY,CAAC,CAAC;QAClC,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;IAED,OAAO,GAAG,CAAC;AACf,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function resolveDependecies(entryPath: string, tempDir: string, reactVersion: string, runtime: string): Promise<void>;
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.resolveDependecies = resolveDependecies;
7
+ const esbuild_1 = require("esbuild");
8
+ const node_child_process_1 = require("node:child_process");
9
+ const node_module_1 = require("node:module");
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const promises_1 = require("fs/promises");
12
+ async function resolveDependecies(entryPath, tempDir, reactVersion, runtime) {
13
+ const missingDeps = await scanDependencies(entryPath);
14
+ if (missingDeps.size > 0) {
15
+ await installDependencies(missingDeps, tempDir, reactVersion, runtime);
16
+ }
17
+ }
18
+ async function scanDependencies(entryPath) {
19
+ const missingDeps = new Set();
20
+ await (0, esbuild_1.build)({
21
+ entryPoints: [entryPath],
22
+ bundle: true,
23
+ write: false,
24
+ plugins: [
25
+ {
26
+ name: 'scan',
27
+ setup(build) {
28
+ build.onResolve({ filter: /^[^.\/]/ }, async (args) => {
29
+ if (args.pluginData?.isInternal)
30
+ return null;
31
+ if (node_path_1.default.isAbsolute(args.path))
32
+ return null;
33
+ if (args.path.startsWith('node:') || node_module_1.builtinModules.includes(args.path))
34
+ return { external: true };
35
+ const result = await build.resolve(args.path, {
36
+ resolveDir: args.resolveDir,
37
+ kind: args.kind,
38
+ pluginData: { isInternal: true },
39
+ });
40
+ if (result.errors.length > 0) {
41
+ const parts = args.path.split('/');
42
+ const pkgName = args.path.startsWith('@') ? `${parts[0]}/${parts[1]}` : parts[0];
43
+ if (/^(@[a-zA-Z0-9_.-]+\/)?[a-zA-Z0-9_.-]+$/.test(pkgName)) {
44
+ missingDeps.add(pkgName);
45
+ }
46
+ return { external: true };
47
+ }
48
+ if (/[\/]node_modules[\/]/.test(result.path)) {
49
+ return { external: true };
50
+ }
51
+ return null;
52
+ });
53
+ },
54
+ },
55
+ ],
56
+ loader: { '.js': 'jsx', '.ts': 'tsx', '.jsx': 'jsx', '.tsx': 'tsx' },
57
+ });
58
+ return missingDeps;
59
+ }
60
+ async function installDependencies(missingDeps, tempDir, reactVersion, runtime) {
61
+ const depsObj = {};
62
+ const depsArray = Array.from(missingDeps).map(dep => {
63
+ if (dep === 'react' || dep === 'react-dom') {
64
+ depsObj[dep] = reactVersion === 'latest' ? '*' : reactVersion;
65
+ return `${dep}@${reactVersion}`;
66
+ }
67
+ depsObj[dep] = '*';
68
+ return dep;
69
+ });
70
+ await (0, promises_1.writeFile)(node_path_1.default.join(tempDir, 'package.json'), JSON.stringify({ name: 'react-on-fly-temp', version: '1.0.0', dependencies: depsObj }, null, 2));
71
+ const installCmd = getInstallCommand(runtime);
72
+ console.log(`⚛️ Using React version: ${reactVersion}
73
+ 📦 Installing missing dependencies with ${installCmd.split(' ')[0]}: ${depsArray.join(', ')}...`);
74
+ (0, node_child_process_1.execSync)(installCmd, { cwd: tempDir, stdio: 'inherit' });
75
+ }
76
+ function getInstallCommand(runtime) {
77
+ const userAgent = process.env.npm_config_user_agent || '';
78
+ if (userAgent.includes('bun'))
79
+ return 'bun install';
80
+ if (userAgent.includes('deno'))
81
+ return 'deno install --node-modules-dir';
82
+ if (userAgent.includes('pnpm'))
83
+ return 'pnpm install';
84
+ if (userAgent.includes('yarn'))
85
+ return 'yarn install';
86
+ if (runtime === 'bun')
87
+ return 'bun install';
88
+ if (runtime === 'deno')
89
+ return 'deno install --node-modules-dir';
90
+ return 'npm install';
91
+ }
92
+ //# sourceMappingURL=dependency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency.js","sourceRoot":"","sources":["../../src/func/dependency.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare function ensureFileExists(inputFile: string): Promise<string>;
2
+ export declare function generateEntryFile(userComponentPath: string, reactVersion: string): Promise<{
3
+ bundlePath: string;
4
+ tempDir: string;
5
+ entryPath: string;
6
+ }>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ensureFileExists = ensureFileExists;
7
+ exports.generateEntryFile = generateEntryFile;
8
+ const promises_1 = require("node:fs/promises");
9
+ const promises_2 = require("node:fs/promises");
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const os_1 = __importDefault(require("os"));
12
+ async function ensureFileExists(inputFile) {
13
+ const absoluteInputPath = node_path_1.default.resolve(process.cwd(), inputFile).replace(/\\/g, '/');
14
+ try {
15
+ await (0, promises_2.access)(absoluteInputPath);
16
+ return absoluteInputPath;
17
+ }
18
+ catch {
19
+ console.error(`❌ Error: File not found (${absoluteInputPath})`);
20
+ process.exit(1);
21
+ }
22
+ }
23
+ async function generateEntryFile(userComponentPath, reactVersion) {
24
+ const tempDir = await (0, promises_1.mkdtemp)(node_path_1.default.join(os_1.default.tmpdir(), 'react-on-fly-'));
25
+ const bundlePath = node_path_1.default.join(tempDir, 'bundle.js');
26
+ const entryPath = node_path_1.default.join(tempDir, 'entry.jsx');
27
+ const parsedVersion = parseInt(reactVersion.split('.')[0], 10);
28
+ const isReact18OrLater = reactVersion === 'latest' || isNaN(parsedVersion) || parsedVersion >= 18;
29
+ const entryCode = `import React from 'react';
30
+ ${isReact18OrLater ?
31
+ `import { createRoot } from 'react-dom/client';
32
+ import UserApp from '${userComponentPath}';
33
+
34
+ const container = document.getElementById('root');
35
+ const root = createRoot(container);
36
+ root.render(React.createElement(UserApp));` :
37
+ `import ReactDOM from 'react-dom';
38
+ import UserApp from '${userComponentPath}';
39
+
40
+ const container = document.getElementById('root');
41
+ ReactDOM.render(React.createElement(UserApp), container);
42
+ `}`;
43
+ await (0, promises_1.writeFile)(entryPath, entryCode);
44
+ return { bundlePath, tempDir, entryPath };
45
+ }
46
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/func/files.ts"],"names":[],"mappings":";;;;;AAMA,4CASC;AACD,8CAyBC;AAzCD,+CAAsD;AACtD,+CAA0C;AAC1C,0DAA6B;AAC7B,4CAAoB;AAGb,KAAK,UAAU,gBAAgB,CAAC,SAAiB;IACpD,MAAM,iBAAiB,GAAG,mBAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACrF,IAAI,CAAC;QACD,MAAM,IAAA,iBAAM,EAAC,iBAAiB,CAAC,CAAC;QAChC,OAAO,iBAAiB,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,CAAC,KAAK,CAAC,4BAA4B,iBAAiB,GAAG,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC;AACM,KAAK,UAAU,iBAAiB,CAAC,iBAAyB,EAAE,YAAoB;IACnF,MAAM,OAAO,GAAG,MAAM,IAAA,kBAAO,EAAC,mBAAI,CAAC,IAAI,CAAC,YAAE,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;IACvE,MAAM,UAAU,GAAG,mBAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IACnD,MAAM,SAAS,GAAG,mBAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAClD,MAAM,aAAa,GAAG,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/D,MAAM,gBAAgB,GAAG,YAAY,KAAK,QAAQ,IAAI,KAAK,CAAC,aAAa,CAAC,IAAI,aAAa,IAAI,EAAE,CAAC;IAElG,MAAM,SAAS,GAAG;EACpB,gBAAgB,CAAC,CAAC;QACR;uBACW,iBAAiB;;;;2CAIG,CAAC,CAAC;QAEjC;uBACW,iBAAiB;;;;CAIvC,EAAE,CAAC;IAEA,MAAM,IAAA,oBAAS,EAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACtC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { BuildContext } from 'esbuild';
2
+ export declare function resolveRuntime(): "bun" | "deno" | "node";
3
+ export declare function createWebServer(PORT: number, bundlePath: string, watchMode: boolean, runtime?: string): Promise<Bun.Server<undefined> | Deno.HttpServer<Deno.NetAddr> | import("node:http").Server<typeof import("node:http").IncomingMessage, typeof import("node:http").ServerResponse>>;
4
+ export declare function setupCleanup(tempDir: string, ctx?: BuildContext): void;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resolveRuntime = resolveRuntime;
37
+ exports.createWebServer = createWebServer;
38
+ exports.setupCleanup = setupCleanup;
39
+ const promises_1 = require("node:fs/promises");
40
+ function resolveRuntime() {
41
+ if (typeof Bun !== 'undefined')
42
+ return 'bun';
43
+ if (typeof Deno !== 'undefined')
44
+ return 'deno';
45
+ return 'node';
46
+ }
47
+ async function createWebServer(PORT, bundlePath, watchMode, runtime = 'node') {
48
+ const content = (0, promises_1.readFile)(bundlePath, 'utf8');
49
+ let server;
50
+ switch (runtime) {
51
+ case 'bun': {
52
+ const { default: bunServer } = await Promise.resolve().then(() => __importStar(require('../server/bun')));
53
+ server = bunServer(PORT, content);
54
+ break;
55
+ }
56
+ case 'deno': {
57
+ const { default: denoServer } = await Promise.resolve().then(() => __importStar(require('../server/deno')));
58
+ server = denoServer(PORT, content);
59
+ break;
60
+ }
61
+ case 'node':
62
+ default: {
63
+ const { default: nodeServer } = await Promise.resolve().then(() => __importStar(require('../server/node')));
64
+ server = nodeServer(PORT, content);
65
+ break;
66
+ }
67
+ }
68
+ console.log(`🚀 Ready! Your component is served at: http://localhost:${PORT}\n${watchMode ? '👀 Watching for file changes...' : ''}\nPress Ctrl+C to stop the process.`);
69
+ return server;
70
+ }
71
+ function setupCleanup(tempDir, ctx) {
72
+ process.on('SIGINT', async () => {
73
+ console.log('\nShutting down the server and cleaning up temporary files...');
74
+ if (ctx) {
75
+ await ctx.dispose();
76
+ }
77
+ await (0, promises_1.rm)(tempDir, { recursive: true, force: true });
78
+ process.exit(0);
79
+ });
80
+ }
81
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/func/server.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,wCAIC;AAAC,0CAuBD;AAED,oCASC;AAzCD,+CAAgD;AAGhD,SAAgB,cAAc;IAC1B,IAAI,OAAO,GAAG,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IAC7C,IAAI,OAAO,IAAI,KAAK,WAAW;QAAE,OAAO,MAAM,CAAC;IAC/C,OAAO,MAAM,CAAC;AAClB,CAAC;AAAQ,KAAK,UAAU,eAAe,CAAC,IAAY,EAAE,UAAkB,EAAE,SAAkB,EAAE,UAAkB,MAAM;IAClH,MAAM,OAAO,GAAG,IAAA,mBAAQ,EAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC7C,IAAI,MAAM,CAAC;IACX,QAAQ,OAAO,EAAE,CAAC;QACd,KAAK,KAAK,CAAC,CAAC,CAAC;YACT,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,wDAAa,eAAe,GAAC,CAAC;YAC7D,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAClC,MAAM;QACV,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACV,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,wDAAa,gBAAgB,GAAC,CAAC;YAC/D,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACnC,MAAM;QACV,CAAC;QACD,KAAK,MAAM,CAAC;QACZ,OAAO,CAAC,CAAC,CAAC;YACN,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,wDAAa,gBAAgB,GAAC,CAAC;YAC/D,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACnC,MAAM;QACV,CAAC;IACL,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,2DAA2D,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,EAAE,qCAAqC,CAAC,CAAC;IACzK,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,SAAgB,YAAY,CAAC,OAAe,EAAE,GAAkB;IAC5D,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;QAC5B,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;QAC7E,IAAI,GAAG,EAAE,CAAC;YACN,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;QACxB,CAAC;QACD,MAAM,IAAA,aAAE,EAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;AACP,CAAC"}
package/dist/main.js ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const dependency_1 = require("./func/dependency");
5
+ const args_1 = require("./func/args");
6
+ const files_1 = require("./func/files");
7
+ const bundle_1 = require("./func/bundle");
8
+ const server_1 = require("./func/server");
9
+ async function main() {
10
+ const { inputFile, PORT, reactVersion, watchMode } = (0, args_1.parseArgs)();
11
+ const absoluteInputPath = await (0, files_1.ensureFileExists)(inputFile);
12
+ const { entryPath, bundlePath, tempDir } = await (0, files_1.generateEntryFile)(absoluteInputPath, reactVersion);
13
+ console.log('🔍 Scanning for missing dependencies...');
14
+ const runtime = (0, server_1.resolveRuntime)();
15
+ await (0, dependency_1.resolveDependecies)(entryPath, tempDir, reactVersion, runtime);
16
+ console.log('⚡ Compiling...');
17
+ const ctx = await (0, bundle_1.bundleCode)(entryPath, bundlePath, tempDir, watchMode);
18
+ console.log(`⚙️ Starting server using ${runtime} runtime`);
19
+ (0, server_1.createWebServer)(PORT, bundlePath, watchMode, runtime).
20
+ finally(() => (0, server_1.setupCleanup)(tempDir, ctx));
21
+ }
22
+ main().catch(console.error);
23
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;;AACA,kDAAuD;AACvD,sCAAwC;AACxC,wCAAmE;AACnE,0CAA2C;AAC3C,0CAA8E;AAE9E,KAAK,UAAU,IAAI;IACf,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,IAAA,gBAAS,GAAE,CAAC;IACjE,MAAM,iBAAiB,GAAG,MAAM,IAAA,wBAAgB,EAAC,SAAS,CAAC,CAAC;IAC5D,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,MAAM,IAAA,yBAAiB,EAAC,iBAAiB,EAAE,YAAY,CAAC,CAAC;IACpG,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,IAAA,uBAAc,GAAE,CAAA;IAChC,MAAM,IAAA,+BAAkB,EAAC,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,MAAM,IAAA,mBAAU,EAAC,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACxE,OAAO,CAAC,GAAG,CAAC,6BAA6B,OAAO,UAAU,CAAC,CAAA;IAC3D,IAAA,wBAAe,EAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC;QACjD,OAAO,CAAC,GAAG,EAAE,CAAC,IAAA,qBAAY,EAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export default function bunServer(PORT: number, content: Promise<string>): Bun.Server<undefined>;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = bunServer;
4
+ function bunServer(PORT, content) {
5
+ const server = Bun.serve({
6
+ port: PORT,
7
+ async fetch(req) {
8
+ const url = new URL(req.url);
9
+ if (url.pathname === '/favicon.ico') {
10
+ return new Response(null, { status: 204 });
11
+ }
12
+ if (url.pathname === '/bundle.js') {
13
+ try {
14
+ return new Response(await content, {
15
+ headers: { 'Content-Type': 'application/javascript' }
16
+ });
17
+ }
18
+ catch (err) {
19
+ if (err.code === 'ENOENT') {
20
+ return new Response('console.error("Bundle not found. Check the terminal for build errors.");', {
21
+ status: 404,
22
+ headers: { 'Content-Type': 'application/javascript' }
23
+ });
24
+ }
25
+ else {
26
+ return new Response(`console.error("Error reading bundle: ${err instanceof Error ? err.message : String(err)}");`, {
27
+ status: 500,
28
+ headers: { 'Content-Type': 'application/javascript' }
29
+ });
30
+ }
31
+ }
32
+ }
33
+ else {
34
+ let usesTailwind = false;
35
+ try {
36
+ usesTailwind = /["'`][^"'`]*\b(bg-[a-z]+-\d+|text-[a-z]+-\d+|border-[a-z]+-\d+|[pm][trblxy]?-[0-9]+|w-[0-9]+|h-[0-9]+|flex|grid|rounded(?:-(?:sm|md|lg|xl|2xl|3xl|full|none))?)\b[^"'`]*["'`]/.test(await content);
37
+ }
38
+ catch (err) { }
39
+ const tailwindScript = usesTailwind ? '<script src="https://cdn.tailwindcss.com"></script>' : '';
40
+ return new Response(`
41
+ <!DOCTYPE html>
42
+ <html lang="en">
43
+ <head>
44
+ <meta charset="UTF-8" />
45
+ <title>React On The Fly</title>
46
+ <link rel="icon" href="data:," />
47
+ ${tailwindScript}
48
+ </head>
49
+ <body>
50
+ <div id="root"></div>
51
+ <script src="/bundle.js"></script>
52
+ </body>
53
+ </html>
54
+ `, {
55
+ headers: { 'Content-Type': 'text/html' }
56
+ });
57
+ }
58
+ }
59
+ });
60
+ return server;
61
+ }
62
+ //# sourceMappingURL=bun.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bun.js","sourceRoot":"","sources":["../../src/server/bun.ts"],"names":[],"mappings":";;AAAA,4BAyDC;AAzDD,SAAwB,SAAS,CAAC,IAAY,EAAE,OAAwB;IACpE,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC;QACrB,IAAI,EAAE,IAAI;QACV,KAAK,CAAC,KAAK,CAAC,GAAY;YACpB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAE7B,IAAI,GAAG,CAAC,QAAQ,KAAK,cAAc,EAAE,CAAC;gBAClC,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YAC/C,CAAC;YAED,IAAI,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;gBAChC,IAAI,CAAC;oBACD,OAAO,IAAI,QAAQ,CAAC,MAAM,OAAO,EAAE;wBAC/B,OAAO,EAAE,EAAE,cAAc,EAAE,wBAAwB,EAAE;qBACxD,CAAC,CAAC;gBACP,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAChB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;wBACxB,OAAO,IAAI,QAAQ,CAAC,0EAA0E,EAAE;4BAC5F,MAAM,EAAE,GAAG;4BACX,OAAO,EAAE,EAAE,cAAc,EAAE,wBAAwB,EAAE;yBACxD,CAAC,CAAC;oBACP,CAAC;yBAAM,CAAC;wBACJ,OAAO,IAAI,QAAQ,CAAC,wCAAwC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE;4BAC/G,MAAM,EAAE,GAAG;4BACX,OAAO,EAAE,EAAE,cAAc,EAAE,wBAAwB,EAAE;yBACxD,CAAC,CAAC;oBACP,CAAC;gBACL,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,IAAI,YAAY,GAAG,KAAK,CAAC;gBACzB,IAAI,CAAC;oBACD,YAAY,GAAG,+KAA+K,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC;gBACvN,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC;gBACjB,MAAM,cAAc,GAAG,YAAY,CAAC,CAAC,CAAC,qDAAqD,CAAC,CAAC,CAAC,EAAE,CAAC;gBAEjG,OAAO,IAAI,QAAQ,CAAC;;;;;;;sBAOd,cAAc;;;;;;;eAOrB,EAAE;oBACG,OAAO,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE;iBAC3C,CAAC,CAAC;YACP,CAAC;QACL,CAAC;KACJ,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACjB,CAAC"}
@@ -0,0 +1 @@
1
+ export default function denoServer(PORT: number, content: Promise<string>): Promise<Deno.HttpServer<Deno.NetAddr>>;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = denoServer;
4
+ async function denoServer(PORT, content) {
5
+ const server = Deno.serve({ port: PORT }, async (req) => {
6
+ const url = new URL(req.url);
7
+ if (url.pathname === '/favicon.ico') {
8
+ return new Response(null, { status: 204 });
9
+ }
10
+ if (url.pathname === '/bundle.js') {
11
+ try {
12
+ return new Response(await content, {
13
+ headers: { 'Content-Type': 'application/javascript' }
14
+ });
15
+ }
16
+ catch (err) {
17
+ if (err.code === 'ENOENT') {
18
+ return new Response('console.error("Bundle not found. Check the terminal for build errors.");', {
19
+ status: 404,
20
+ headers: { 'Content-Type': 'application/javascript' }
21
+ });
22
+ }
23
+ else {
24
+ return new Response(`console.error("Error reading bundle: ${err instanceof Error ? err.message : String(err)}");`, {
25
+ status: 500,
26
+ headers: { 'Content-Type': 'application/javascript' }
27
+ });
28
+ }
29
+ }
30
+ }
31
+ else {
32
+ let usesTailwind = false;
33
+ try {
34
+ usesTailwind = /["'`][^"'`]*\b(bg-[a-z]+-\d+|text-[a-z]+-\d+|border-[a-z]+-\d+|[pm][trblxy]?-[0-9]+|w-[0-9]+|h-[0-9]+|flex|grid|rounded(?:-(?:sm|md|lg|xl|2xl|3xl|full|none))?)\b[^"'`]*["'`]/.test(await content);
35
+ }
36
+ catch (err) { }
37
+ const tailwindScript = usesTailwind ? '<script src="https://cdn.tailwindcss.com"></script>' : '';
38
+ return new Response(`
39
+ <!DOCTYPE html>
40
+ <html lang="en">
41
+ <head>
42
+ <meta charset="UTF-8" />
43
+ <title>React On The Fly</title>
44
+ <link rel="icon" href="data:," />
45
+ ${tailwindScript}
46
+ </head>
47
+ <body>
48
+ <div id="root"></div>
49
+ <script src="/bundle.js"></script>
50
+ </body>
51
+ </html>
52
+ `, {
53
+ headers: { 'Content-Type': 'text/html' }
54
+ });
55
+ }
56
+ });
57
+ return server;
58
+ }
59
+ //# sourceMappingURL=deno.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deno.js","sourceRoot":"","sources":["../../src/server/deno.ts"],"names":[],"mappings":";;AAAA,6BAsDC;AAtDc,KAAK,UAAU,UAAU,CAAC,IAAY,EAAE,OAAuB;IAC1E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,EAAE;QACzD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE7B,IAAI,GAAG,CAAC,QAAQ,KAAK,cAAc,EAAE,CAAC;YAClC,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/C,CAAC;QAED,IAAI,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;YAChC,IAAI,CAAC;gBACD,OAAO,IAAI,QAAQ,CAAC,MAAM,OAAO,EAAE;oBAC/B,OAAO,EAAE,EAAE,cAAc,EAAE,wBAAwB,EAAE;iBACxD,CAAC,CAAC;YACP,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAChB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACxB,OAAO,IAAI,QAAQ,CAAC,0EAA0E,EAAE;wBAC5F,MAAM,EAAE,GAAG;wBACX,OAAO,EAAE,EAAE,cAAc,EAAE,wBAAwB,EAAE;qBACxD,CAAC,CAAC;gBACP,CAAC;qBAAM,CAAC;oBACJ,OAAO,IAAI,QAAQ,CAAC,wCAAwC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE;wBAC/G,MAAM,EAAE,GAAG;wBACX,OAAO,EAAE,EAAE,cAAc,EAAE,wBAAwB,EAAE;qBACxD,CAAC,CAAC;gBACP,CAAC;YACL,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,IAAI,YAAY,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC;gBACD,YAAY,GAAG,+KAA+K,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC;YACvN,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC;YACjB,MAAM,cAAc,GAAG,YAAY,CAAC,CAAC,CAAC,qDAAqD,CAAC,CAAC,CAAC,EAAE,CAAC;YAEjG,OAAO,IAAI,QAAQ,CAAC;;;;;;;sBAOd,cAAc;;;;;;;eAOrB,EAAE;gBACG,OAAO,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE;aAC3C,CAAC,CAAC;QACP,CAAC;IACT,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAA;AACjB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import http from 'http';
2
+ export default function nodeServer(PORT: number, content: Promise<string>): http.Server;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = nodeServer;
7
+ const http_1 = __importDefault(require("http"));
8
+ function nodeServer(PORT, content) {
9
+ const server = http_1.default.createServer(async (req, res) => {
10
+ req.on('error', () => { });
11
+ if (req.url === '/favicon.ico') {
12
+ if (!res.headersSent)
13
+ res.writeHead(204);
14
+ return res.end();
15
+ }
16
+ if (req.url === '/bundle.js') {
17
+ try {
18
+ if (!res.headersSent)
19
+ res.writeHead(200, { 'Content-Type': 'application/javascript' });
20
+ res.end(await content);
21
+ }
22
+ catch (err) {
23
+ if (err.code === 'ENOENT') {
24
+ if (!res.headersSent)
25
+ res.writeHead(404, { 'Content-Type': 'application/javascript' });
26
+ res.end('console.error("Bundle not found. Check the terminal for build errors.");');
27
+ }
28
+ else {
29
+ if (!res.headersSent)
30
+ res.writeHead(500, { 'Content-Type': 'application/javascript' });
31
+ return res.end(`console.error("Error reading bundle: ${err instanceof Error ? err.message : String(err)}");`);
32
+ }
33
+ }
34
+ }
35
+ else {
36
+ let usesTailwind = false;
37
+ try {
38
+ usesTailwind = /["'`][^"'`]*\b(bg-[a-z]+-\d+|text-[a-z]+-\d+|border-[a-z]+-\d+|[pm][trblxy]?-[0-9]+|w-[0-9]+|h-[0-9]+|flex|grid|rounded(?:-(?:sm|md|lg|xl|2xl|3xl|full|none))?)\b[^"'`]*["'`]/.test(await content);
39
+ }
40
+ catch (err) { }
41
+ const tailwindScript = usesTailwind ? '<script src="https://cdn.tailwindcss.com"></script>' : '';
42
+ if (!res.headersSent)
43
+ res.writeHead(200, { 'Content-Type': 'text/html' });
44
+ res.end(`
45
+ <!DOCTYPE html>
46
+ <html lang="en">
47
+ <head>
48
+ <meta charset="UTF-8" />
49
+ <title>React On The Fly</title>
50
+ <link rel="icon" href="data:," />
51
+ ${tailwindScript}
52
+ </head>
53
+ <body>
54
+ <div id="root"></div>
55
+ <script src="/bundle.js"></script>
56
+ </body>
57
+ </html>
58
+ `);
59
+ }
60
+ });
61
+ server.listen(PORT);
62
+ return server;
63
+ }
64
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/server/node.ts"],"names":[],"mappings":";;;;;AAEA,6BAmDC;AArDD,gDAAwB;AAExB,SAAwB,UAAU,CAAC,IAAY,EAAE,OAAwB;IACrE,MAAM,MAAM,GAAG,cAAI,CAAC,YAAY,CAAC,KAAK,EAAE,GAAyB,EAAE,GAAwB,EAAE,EAAE;QAC3F,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QAE3B,IAAI,GAAG,CAAC,GAAG,KAAK,cAAc,EAAE,CAAC;YAC7B,IAAI,CAAC,GAAG,CAAC,WAAW;gBAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACzC,OAAO,GAAG,CAAC,GAAG,EAAE,CAAC;QACrB,CAAC;QAED,IAAI,GAAG,CAAC,GAAG,KAAK,YAAY,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACD,IAAI,CAAC,GAAG,CAAC,WAAW;oBAAE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,wBAAwB,EAAE,CAAC,CAAC;gBACvF,GAAG,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;YAC3B,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAChB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACxB,IAAI,CAAC,GAAG,CAAC,WAAW;wBAAE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,wBAAwB,EAAE,CAAC,CAAC;oBACvF,GAAG,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC;gBACxF,CAAC;qBAAM,CAAC;oBACJ,IAAI,CAAC,GAAG,CAAC,WAAW;wBAAE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,wBAAwB,EAAE,CAAC,CAAC;oBACvF,OAAO,GAAG,CAAC,GAAG,CAAC,wCAAwC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAClH,CAAC;YACL,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,IAAI,YAAY,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC;gBACD,YAAY,GAAG,+KAA+K,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC;YACvN,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC;YACjB,MAAM,cAAc,GAAG,YAAY,CAAC,CAAC,CAAC,qDAAqD,CAAC,CAAC,CAAC,EAAE,CAAC;YAEjG,IAAI,CAAC,GAAG,CAAC,WAAW;gBAAE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;YAC1E,GAAG,CAAC,GAAG,CAAC;;;;;;;cAON,cAAc;;;;;;;OAOrB,CAAC,CAAC;QACD,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAEpB,OAAO,MAAM,CAAC;AAClB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-on-fly",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "description": "Compile and serve a react file on the fly",
5
5
  "engines": {
6
6
  "node": ">=18.0.0",
@@ -11,9 +11,10 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/zMattew/react-fly/issues"
13
13
  },
14
- "main": "dist/cli.js",
14
+ "main": "dist/main.js",
15
15
  "author": "zMattew_",
16
16
  "license": "MIT",
17
+ "type": "commonjs",
17
18
  "repository": "zMattew/react-fly",
18
19
  "keywords": [
19
20
  "react",
@@ -31,9 +32,11 @@
31
32
  "dev-server"
32
33
  ],
33
34
  "bin": {
34
- "react-on-fly": "./dist/cli.js"
35
+ "react-on-fly": "./dist/main.js"
35
36
  },
36
- "files": ["dist"],
37
+ "files": [
38
+ "dist"
39
+ ],
37
40
  "scripts": {
38
41
  "build": "tsc",
39
42
  "prepublishOnly": "npm run build",
@@ -43,6 +46,8 @@
43
46
  "esbuild": "^0.27.4"
44
47
  },
45
48
  "devDependencies": {
49
+ "@types/bun": "^1.3.11",
50
+ "@types/deno": "^2.5.0",
46
51
  "@types/node": "^25.5.0",
47
52
  "typescript": "^6.0.1-rc"
48
53
  }
package/dist/cli.js DELETED
@@ -1,261 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- const path_1 = __importDefault(require("path"));
8
- const promises_1 = __importDefault(require("fs/promises"));
9
- const http_1 = __importDefault(require("http"));
10
- const esbuild_1 = require("esbuild");
11
- const os_1 = __importDefault(require("os"));
12
- const module_1 = require("module");
13
- const child_process_1 = require("child_process");
14
- async function main() {
15
- const { inputFile, PORT, reactVersion, watchMode } = parseArgs();
16
- const absoluteInputPath = await ensureFileExists(inputFile);
17
- const { entryPath, bundlePath, tempDir } = await generateEntryFile(absoluteInputPath, reactVersion);
18
- console.log('🔍 Scanning for missing dependencies...');
19
- await resolveDependecies(entryPath, tempDir, reactVersion);
20
- console.log('⚡ Compiling...');
21
- const ctx = await bundleCode(entryPath, bundlePath, tempDir, watchMode);
22
- createWebServer(PORT, bundlePath, watchMode);
23
- setupCleanup(tempDir, ctx);
24
- }
25
- function parseArgs() {
26
- const inputFile = process.argv[2];
27
- if (!inputFile || inputFile.startsWith('-')) {
28
- console.error('❌ Error: You must specify a file to compile as the first argument.');
29
- console.log('💡 Usage: react-on-fly <file.js|jsx|ts|tsx> [-p <port>] [-rv <version>] [-w <boolean>]');
30
- process.exit(1);
31
- }
32
- let PORT = 3000;
33
- let reactVersion = 'latest';
34
- let watchMode = false;
35
- const args = process.argv.slice(3);
36
- for (let i = 0; i < args.length; i++) {
37
- const arg = args[i];
38
- switch (arg) {
39
- case '-p':
40
- const parsedPort = parseInt(args[++i], 10);
41
- if (!isNaN(parsedPort) && parsedPort > 0)
42
- PORT = parsedPort;
43
- break;
44
- case '-rv':
45
- reactVersion = args[++i] || 'latest';
46
- break;
47
- case '-w':
48
- const nextArg = args[i + 1];
49
- if (nextArg === 'true' || nextArg === 'false') {
50
- watchMode = nextArg === 'true';
51
- i++;
52
- }
53
- else
54
- watchMode = true;
55
- break;
56
- }
57
- }
58
- return { inputFile, PORT, reactVersion, watchMode };
59
- }
60
- async function ensureFileExists(inputFile) {
61
- const absoluteInputPath = path_1.default.resolve(process.cwd(), inputFile).replace(/\\/g, '/');
62
- try {
63
- await promises_1.default.access(absoluteInputPath);
64
- return absoluteInputPath;
65
- }
66
- catch {
67
- console.error(`❌ Error: File not found (${absoluteInputPath})`);
68
- process.exit(1);
69
- }
70
- }
71
- async function generateEntryFile(userComponentPath, reactVersion) {
72
- const tempDir = await promises_1.default.mkdtemp(path_1.default.join(os_1.default.tmpdir(), 'react-on-fly-'));
73
- const bundlePath = path_1.default.join(tempDir, 'bundle.js');
74
- const entryPath = path_1.default.join(tempDir, 'entry.jsx');
75
- const parsedVersion = parseInt(reactVersion.split('.')[0], 10);
76
- const isReact18OrLater = reactVersion === 'latest' || isNaN(parsedVersion) || parsedVersion >= 18;
77
- const entryCode = `import React from 'react';
78
- ${isReact18OrLater ?
79
- `import { createRoot } from 'react-dom/client';
80
- import UserApp from '${userComponentPath}';
81
-
82
- const container = document.getElementById('root');
83
- const root = createRoot(container);
84
- root.render(React.createElement(UserApp));` :
85
- `import ReactDOM from 'react-dom';
86
- import UserApp from '${userComponentPath}';
87
-
88
- const container = document.getElementById('root');
89
- ReactDOM.render(React.createElement(UserApp), container);
90
- `}`;
91
- await promises_1.default.writeFile(entryPath, entryCode);
92
- return { bundlePath, tempDir, entryPath };
93
- }
94
- async function resolveDependecies(entryPath, tempDir, reactVersion) {
95
- const missingDeps = await scanDependencies(entryPath);
96
- if (missingDeps.size > 0) {
97
- await installDependencies(missingDeps, tempDir, reactVersion);
98
- }
99
- }
100
- async function scanDependencies(entryPath) {
101
- const missingDeps = new Set();
102
- await (0, esbuild_1.build)({
103
- entryPoints: [entryPath],
104
- bundle: true,
105
- write: false,
106
- plugins: [
107
- {
108
- name: 'scan',
109
- setup(build) {
110
- build.onResolve({ filter: /^[^.\/]/ }, async (args) => {
111
- if (args.pluginData?.isInternal)
112
- return null;
113
- if (path_1.default.isAbsolute(args.path))
114
- return null;
115
- if (args.path.startsWith('node:') || module_1.builtinModules.includes(args.path))
116
- return { external: true };
117
- const result = await build.resolve(args.path, {
118
- resolveDir: args.resolveDir,
119
- kind: args.kind,
120
- pluginData: { isInternal: true },
121
- });
122
- if (result.errors.length > 0) {
123
- const parts = args.path.split('/');
124
- const pkgName = args.path.startsWith('@') ? `${parts[0]}/${parts[1]}` : parts[0];
125
- if (/^(@[a-zA-Z0-9_.-]+\/)?[a-zA-Z0-9_.-]+$/.test(pkgName)) {
126
- missingDeps.add(pkgName);
127
- }
128
- return { external: true };
129
- }
130
- if (/[\/]node_modules[\/]/.test(result.path)) {
131
- return { external: true };
132
- }
133
- return null;
134
- });
135
- },
136
- },
137
- ],
138
- loader: { '.js': 'jsx', '.ts': 'tsx', '.jsx': 'jsx', '.tsx': 'tsx' },
139
- });
140
- return missingDeps;
141
- }
142
- async function installDependencies(missingDeps, tempDir, reactVersion) {
143
- const depsObj = {};
144
- const depsArray = Array.from(missingDeps).map(dep => {
145
- if (dep === 'react' || dep === 'react-dom') {
146
- depsObj[dep] = reactVersion === 'latest' ? '*' : reactVersion;
147
- return `${dep}@${reactVersion}`;
148
- }
149
- depsObj[dep] = '*';
150
- return dep;
151
- });
152
- console.log(`⚛️ Using React version: ${reactVersion}
153
- 📦 Installing missing dependencies: ${depsArray.join(', ')}...`);
154
- await promises_1.default.writeFile(path_1.default.join(tempDir, 'package.json'), JSON.stringify({ name: 'react-on-fly-temp', version: '1.0.0', dependencies: depsObj }, null, 2));
155
- let installCmd = 'npm install';
156
- const userAgent = process.env.npm_config_user_agent || '';
157
- // @ts-ignore
158
- if (typeof Bun !== 'undefined' || userAgent.includes('bun')) {
159
- installCmd = 'bun install';
160
- // @ts-ignore
161
- }
162
- else if (typeof Deno !== 'undefined') {
163
- installCmd = 'deno install --node-modules-dir';
164
- }
165
- else if (userAgent.includes('pnpm')) {
166
- installCmd = 'pnpm install';
167
- }
168
- else if (userAgent.includes('yarn')) {
169
- installCmd = 'yarn install';
170
- }
171
- (0, child_process_1.execSync)(installCmd, { cwd: tempDir, stdio: 'inherit' });
172
- }
173
- async function bundleCode(entryPath, bundlePath, tempDir, watchMode) {
174
- const buildOptions = {
175
- entryPoints: [entryPath],
176
- bundle: true,
177
- outfile: bundlePath,
178
- format: 'iife',
179
- loader: { '.js': 'jsx', '.ts': 'tsx', '.jsx': 'jsx', '.tsx': 'tsx' },
180
- nodePaths: [path_1.default.join(tempDir, 'node_modules')]
181
- };
182
- let ctx;
183
- if (!watchMode)
184
- await (0, esbuild_1.build)(buildOptions);
185
- else {
186
- ctx = await (0, esbuild_1.context)(buildOptions);
187
- await ctx.watch();
188
- }
189
- return ctx;
190
- }
191
- function createWebServer(PORT, bundlePath, watchMode) {
192
- const server = http_1.default.createServer(async (req, res) => {
193
- req.on('error', () => { });
194
- if (req.url === '/favicon.ico') {
195
- if (!res.headersSent)
196
- res.writeHead(204);
197
- return res.end();
198
- }
199
- if (req.url === '/bundle.js') {
200
- try {
201
- const content = await promises_1.default.readFile(bundlePath);
202
- if (!res.headersSent)
203
- res.writeHead(200, { 'Content-Type': 'application/javascript' });
204
- res.end(content);
205
- }
206
- catch (err) {
207
- if (err.code === 'ENOENT') {
208
- if (!res.headersSent)
209
- res.writeHead(404, { 'Content-Type': 'application/javascript' });
210
- res.end('console.error("Bundle not found. Check the terminal for build errors.");');
211
- }
212
- else {
213
- if (!res.headersSent)
214
- res.writeHead(500, { 'Content-Type': 'application/javascript' });
215
- return res.end(`console.error("Error reading bundle: ${err instanceof Error ? err.message : String(err)}");`);
216
- }
217
- }
218
- }
219
- else {
220
- let usesTailwind = false;
221
- try {
222
- const bundleCode = await promises_1.default.readFile(bundlePath, 'utf8');
223
- usesTailwind = /["'`][^"'`]*\b(bg-[a-z]+-\d+|text-[a-z]+-\d+|border-[a-z]+-\d+|[pm][trblxy]?-[0-9]+|w-[0-9]+|h-[0-9]+|flex|grid|rounded(?:-(?:sm|md|lg|xl|2xl|3xl|full|none))?)\b[^"'`]*["'`]/.test(bundleCode);
224
- }
225
- catch (err) { }
226
- const tailwindScript = usesTailwind ? '<script src="https://cdn.tailwindcss.com"></script>' : '';
227
- if (!res.headersSent)
228
- res.writeHead(200, { 'Content-Type': 'text/html' });
229
- res.end(`
230
- <!DOCTYPE html>
231
- <html lang="en">
232
- <head>
233
- <meta charset="UTF-8" />
234
- <title>React On The Fly</title>
235
- <link rel="icon" href="data:," />
236
- ${tailwindScript}
237
- </head>
238
- <body>
239
- <div id="root"></div>
240
- <script src="/bundle.js"></script>
241
- </body>
242
- </html>
243
- `);
244
- }
245
- });
246
- server.listen(PORT, () => {
247
- console.log(`🚀 Ready! Your component is served at: http://localhost:${PORT}\n${watchMode ? '👀 Watching for file changes...' : ''}\nPress Ctrl+C to stop the process.`);
248
- });
249
- return server;
250
- }
251
- function setupCleanup(tempDir, ctx) {
252
- process.on('SIGINT', async () => {
253
- console.log('\nShutting down the server and cleaning up temporary files...');
254
- if (ctx) {
255
- await ctx.dispose();
256
- }
257
- await promises_1.default.rm(tempDir, { recursive: true, force: true });
258
- process.exit(0);
259
- });
260
- }
261
- main().catch(console.error);
File without changes