@jetstart/core 1.6.0 → 2.0.0

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 (40) hide show
  1. package/README.md +189 -74
  2. package/dist/build/dex-generator.d.ts +27 -0
  3. package/dist/build/dex-generator.js +202 -0
  4. package/dist/build/dsl-parser.d.ts +3 -30
  5. package/dist/build/dsl-parser.js +67 -240
  6. package/dist/build/dsl-types.d.ts +8 -0
  7. package/dist/build/gradle.d.ts +51 -0
  8. package/dist/build/gradle.js +233 -1
  9. package/dist/build/hot-reload-service.d.ts +36 -0
  10. package/dist/build/hot-reload-service.js +179 -0
  11. package/dist/build/js-compiler-service.d.ts +61 -0
  12. package/dist/build/js-compiler-service.js +421 -0
  13. package/dist/build/kotlin-compiler.d.ts +54 -0
  14. package/dist/build/kotlin-compiler.js +450 -0
  15. package/dist/build/kotlin-parser.d.ts +91 -0
  16. package/dist/build/kotlin-parser.js +1030 -0
  17. package/dist/build/override-generator.d.ts +54 -0
  18. package/dist/build/override-generator.js +430 -0
  19. package/dist/server/index.d.ts +16 -1
  20. package/dist/server/index.js +147 -42
  21. package/dist/websocket/handler.d.ts +20 -4
  22. package/dist/websocket/handler.js +73 -38
  23. package/dist/websocket/index.d.ts +8 -0
  24. package/dist/websocket/index.js +15 -11
  25. package/dist/websocket/manager.d.ts +2 -2
  26. package/dist/websocket/manager.js +1 -1
  27. package/package.json +3 -3
  28. package/src/build/dex-generator.ts +197 -0
  29. package/src/build/dsl-parser.ts +73 -272
  30. package/src/build/dsl-types.ts +9 -0
  31. package/src/build/gradle.ts +259 -1
  32. package/src/build/hot-reload-service.ts +178 -0
  33. package/src/build/js-compiler-service.ts +411 -0
  34. package/src/build/kotlin-compiler.ts +460 -0
  35. package/src/build/kotlin-parser.ts +1043 -0
  36. package/src/build/override-generator.ts +478 -0
  37. package/src/server/index.ts +162 -54
  38. package/src/websocket/handler.ts +94 -56
  39. package/src/websocket/index.ts +27 -14
  40. package/src/websocket/manager.ts +2 -2
package/README.md CHANGED
@@ -1,124 +1,239 @@
1
- # @jetstart/core
1
+ # @jetstart/core
2
2
 
3
- Core build server and orchestration for JetStart.
3
+ Central build server and real-time orchestration layer for JetStart.
4
4
 
5
5
  ## Overview
6
6
 
7
- The Core package is the central hub of JetStart, responsible for:
7
+ `@jetstart/core` is the engine that powers `jetstart`. It runs three networked services and orchestrates the complete hot reload pipeline from detecting a file change to having new code running on a physical Android device in under 100ms.
8
8
 
9
- - 🏗️ **Build Management** - Compiling Kotlin/Compose projects
10
- - 🌐 **HTTP Server** - Serving APKs and REST API
11
- - 🔌 **WebSocket Server** - Real-time communication with clients
12
- - 📦 **Build Caching** - Faster incremental builds
13
- - 👀 **File Watching** - Auto-rebuild on changes
14
- - 🔐 **Session Management** - Secure device pairing
9
+ ```
10
+ src/
11
+ ├── build/
12
+ │ ├── kotlin-compiler.ts # Invokes kotlinc, builds classpath from SDK + Gradle caches
13
+ │ ├── dex-generator.ts # Runs d8 to convert .class files to classes.dex
14
+ │ ├── override-generator.ts # Generates $Override companion classes (InstantRun-style)
15
+ │ ├── hot-reload-service.ts # Orchestrates compile → override → dex pipeline
16
+ │ ├── gradle.ts # GradleExecutor + AdbHelper for full builds
17
+ │ ├── gradle-injector.ts # Injects JetStart plugin config into build.gradle
18
+ │ ├── watcher.ts # chokidar-based file watcher with debounce
19
+ │ ├── builder.ts # High-level build manager
20
+ │ ├── cache.ts # Incremental build cache
21
+ │ ├── parser.ts # Gradle output parser
22
+ │ ├── dsl-parser.ts # Compose DSL parser
23
+ │ └── js-compiler-service.ts # kotlinc-js → ES module for web emulator
24
+ ├── server/
25
+ │ ├── http.ts # Express HTTP server setup
26
+ │ ├── routes.ts # REST API routes
27
+ │ └── middleware.ts # Request middleware
28
+ ├── websocket/
29
+ │ ├── manager.ts # Connection registry, session routing
30
+ │ ├── handler.ts # Message dispatch + session/token validation
31
+ │ └── index.ts
32
+ ├── utils/
33
+ │ ├── logger.ts # Colored terminal logger
34
+ │ ├── qr.ts # QR code generation
35
+ │ └── session.ts # Session creation and lifecycle
36
+ └── types/
37
+ └── index.ts # ServerSession, QRCodeOptions
38
+ ```
39
+
40
+ ---
41
+
42
+ ## Architecture
43
+
44
+ ```
45
+ File change detected (chokidar — watches *.kt, *.xml, *.gradle, 300ms debounce)
46
+
47
+ ├─► KotlinCompiler
48
+ │ kotlinc + Compose compiler plugin (bundled in Kotlin 2.0+, or Gradle cache fallback)
49
+ │ Classpath: android.jar + Gradle module cache + transforms-3 cache + project build outputs
50
+ │ Uses @argfile to avoid Windows command-line length limits
51
+ │ → .class files in a temp directory
52
+
53
+ ├─► OverrideGenerator
54
+ │ Generates $Override companion classes for each modified class (InstantRun pattern)
55
+ │ Compiles override source files back through KotlinCompiler
56
+ │ Falls back to direct class reload if override generation fails
57
+
58
+ ├─► DexGenerator
59
+ │ Runs d8 from $ANDROID_HOME/build-tools/<latest>
60
+ │ --min-api 24 (Android 7.0+)
61
+ │ → classes.dex
62
+
63
+ └─► WebSocketHandler.sendDexReload()
64
+ Broadcasts base64-encoded DEX + class name list to all authenticated Android clients
65
+ Android runtime loads classes via custom ClassLoader — no reinstall needed
66
+ ```
67
+
68
+ For the web emulator, a parallel path compiles via `kotlinc-js` to an ES module and broadcasts it as `core:js-update`.
69
+
70
+ ---
15
71
 
16
72
  ## Usage
17
73
 
18
- ### As a Library
19
74
  ```typescript
20
75
  import { JetStartServer } from '@jetstart/core';
21
76
 
22
77
  const server = new JetStartServer({
23
78
  httpPort: 8765,
24
79
  wsPort: 8766,
25
- host: '0.0.0.0',
80
+ host: '0.0.0.0', // Bind to all interfaces
81
+ displayHost: '192.168.1.5', // LAN IP used in QR code and terminal output
82
+ projectPath: '/path/to/my-app',
83
+ projectName: 'my-app',
84
+ // For Android emulators — host is reachable at 10.0.2.2 inside the AVD
85
+ emulatorHost: '10.0.2.2',
26
86
  });
27
87
 
28
- await server.start();
29
- ```
88
+ const session = await server.start();
89
+ // session.id and session.token are embedded in the QR code
90
+
91
+ server.on('build:complete', (result) => {
92
+ console.log('APK ready:', result.apkPath);
93
+ });
30
94
 
31
- ### As a Standalone Server
32
- ```bash
33
- npm run start
95
+ await server.stop();
34
96
  ```
35
97
 
36
- ## API Endpoints
98
+ ---
37
99
 
38
- ### HTTP REST API
100
+ ## HTTP API
39
101
 
40
- **Health Check**
41
- ```
42
- GET /health
43
- Response: { status: 'ok', version: '0.1.0', uptime: 123 }
44
- ```
102
+ All endpoints are served on the HTTP port (default `8765`).
45
103
 
46
- **Create Session**
47
- ```
48
- POST /session/create
49
- Body: { projectName: 'MyApp', projectPath: '/path/to/project' }
50
- Response: { session: {...}, qrCode: 'data:image/png;base64,...' }
51
- ```
104
+ ### `GET /`
105
+ Redirects to `https://web.jetstart.site` with the active session's connection parameters (`host`, `port`, `wsPort`, `sessionId`, `token`, `version`, `projectName`) as query parameters, so the web emulator connects automatically. Returns a plain status page if no session is active.
52
106
 
53
- **Get Session**
107
+ ### `GET /health`
108
+ ```json
109
+ { "status": "ok", "version": "0.1.0", "uptime": 42.3 }
54
110
  ```
55
- GET /session/:sessionId
56
- Response: { id, token, projectName, ... }
111
+
112
+ ### `GET /version`
113
+ ```json
114
+ { "version": "0.1.0" }
57
115
  ```
58
116
 
59
- **Download APK**
117
+ ### `POST /session/create`
118
+ Creates a new dev session and returns a base64 QR code PNG.
119
+
120
+ Request body:
121
+ ```json
122
+ { "projectName": "my-app", "projectPath": "/abs/path/to/my-app" }
60
123
  ```
61
- GET /download/:sessionId/:filename
62
- Response: APK file download
124
+
125
+ Response:
126
+ ```json
127
+ {
128
+ "session": { "id": "abc123", "token": "xyz789", "projectName": "my-app", "createdAt": 1711900000000 },
129
+ "qrCode": "data:image/png;base64,..."
130
+ }
63
131
  ```
64
132
 
65
- ### WebSocket Messages
133
+ ### `GET /session/:sessionId`
134
+ Returns the session object (404 if not found).
66
135
 
67
- **Client Core:**
68
- - `client:connect` - Initial connection with session
69
- - `client:status` - Status update
70
- - `client:log` - Log message
71
- - `client:heartbeat` - Keep-alive ping
136
+ ### `GET /download/:filename`
137
+ Streams the most recently built APK as a file download.
72
138
 
73
- **Core → Client:**
74
- - `core:connected` - Connection confirmed
75
- - `core:build-start` - Build started
76
- - `core:build-status` - Build progress update
77
- - `core:build-complete` - Build finished
78
- - `core:build-error` - Build failed
79
- - `core:reload` - Trigger app reload
139
+ ---
80
140
 
81
- ## Build System
82
- ```typescript
83
- import { BuildManager } from '@jetstart/core';
141
+ ## WebSocket Protocol
142
+
143
+ The WebSocket server runs on port `8766`. Every client must send `client:connect` with the matching `sessionId` and `token` (both embedded in the QR code). Mismatched connections are closed immediately:
144
+
145
+ - Close code `4001` — session mismatch (device built against a different session, rescan QR)
146
+ - Close code `4002` — token mismatch
84
147
 
85
- const buildManager = new BuildManager();
148
+ ### Messages: device/browser core
86
149
 
87
- const result = await buildManager.build({
150
+ | Type | Key fields | Description |
151
+ |---|---|---|
152
+ | `client:connect` | `sessionId`, `token`, `deviceInfo` | Authenticate with session credentials |
153
+ | `client:status` | `status` | Send a `SessionStatus` update |
154
+ | `client:log` | `log: LogEntry` | Forward a device log entry to the server |
155
+ | `client:heartbeat` | — | Keep-alive ping |
156
+ | `client:disconnect` | `reason?` | Graceful disconnect |
157
+ | `client:click` | `action`, `elementType`, `elementText?` | UI interaction from web emulator |
158
+
159
+ ### Messages: core → device/browser
160
+
161
+ | Type | Key fields | Description |
162
+ |---|---|---|
163
+ | `core:connected` | `projectName` | Authentication accepted |
164
+ | `core:build-start` | — | Gradle build has begun |
165
+ | `core:build-status` | `status: BuildStatus` | Mid-build progress update |
166
+ | `core:build-complete` | `apkInfo`, `downloadUrl` | APK ready for download/install |
167
+ | `core:build-error` | `error`, `details?` | Build failed |
168
+ | `core:dex-reload` | `dexBase64`, `classNames[]` | Hot reload DEX patch for Android devices |
169
+ | `core:js-update` | `jsBase64`, `sourceFile`, `byteSize` | ES module update for the web emulator |
170
+ | `core:log` | `log: LogEntry` | Device log broadcast to dashboard clients |
171
+ | `core:disconnect` | `reason` | Server shutting down |
172
+
173
+ ---
174
+
175
+ ## File Watcher
176
+
177
+ ```typescript
178
+ import { FileWatcher } from '@jetstart/core';
179
+
180
+ const watcher = new FileWatcher({
88
181
  projectPath: '/path/to/project',
89
- outputPath: './build',
90
- buildType: 'debug',
91
- debuggable: true,
92
- minifyEnabled: false,
93
- versionCode: 1,
94
- versionName: '1.0.0',
95
- applicationId: 'com.example.app',
182
+ callback: (changedFiles) => { /* handle changes */ },
183
+ debounceMs: 300,
96
184
  });
97
185
 
98
- console.log(result.success, result.apkPath);
186
+ watcher.watch('/path/to/project');
187
+ // Watches **/*.kt, **/*.xml, **/*.gradle, **/*.gradle.kts
188
+ // Ignores: node_modules, build, .gradle, .git, dist
189
+
190
+ watcher.stop();
99
191
  ```
100
192
 
101
- ## File Watching
193
+ ---
194
+
195
+ ## Hot Reload Service
196
+
102
197
  ```typescript
103
- import { FileWatcher } from '@jetstart/core';
198
+ import { HotReloadService } from '@jetstart/core';
104
199
 
105
- const watcher = new FileWatcher('/path/to/project');
200
+ const service = new HotReloadService('/path/to/project');
106
201
 
107
- watcher.start(() => {
108
- console.log('Files changed, rebuilding...');
109
- });
202
+ // Check that kotlinc and d8 are available
203
+ const env = await service.checkEnvironment();
204
+ if (!env.ready) console.log(env.issues);
110
205
 
111
- // Later
112
- watcher.stop();
206
+ // Compile a changed file and get the DEX payload
207
+ const result = await service.hotReload('/path/to/project/app/src/main/java/com/example/MainActivity.kt');
208
+ if (result.success) {
209
+ console.log(`Done in ${result.compileTime + result.dexTime}ms`);
210
+ // result.dexBase64 — send this to the device
211
+ // result.classNames — fully-qualified class names patched
212
+ }
113
213
  ```
114
214
 
215
+ ---
216
+
217
+ ## Gradle & ADB
218
+
219
+ `GradleExecutor` runs full Gradle builds (debug or release). It prefers system Gradle over the project `gradlew` wrapper for speed, auto-creates `local.properties` if the Android SDK is found but not configured, and supports Gradle build flags `--parallel --build-cache --configure-on-demand --daemon`.
220
+
221
+ `AdbHelper` handles wireless ADB connections with retry logic (up to 5 attempts, escalating delays) to account for user-approval timing on the device, and polls for device readiness after `adb connect` since the device may transition through `connecting` → `offline` → `device` states.
222
+
223
+ ---
224
+
115
225
  ## Environment Variables
116
226
 
117
- - `PORT` - HTTP server port (default: 8765)
118
- - `WS_PORT` - WebSocket server port (default: 8766)
119
- - `HOST` - Server host (default: 0.0.0.0)
120
- - `DEBUG` - Enable debug logging
227
+ | Variable | Description |
228
+ |---|---|
229
+ | `ANDROID_HOME` / `ANDROID_SDK_ROOT` | Android SDK path — required for hot reload and Gradle builds |
230
+ | `KOTLIN_HOME` | Kotlin installation path — used to find `kotlinc` |
231
+ | `JAVA_HOME` | JDK path |
232
+ | `DEBUG` | Enable verbose logging |
233
+
234
+ ---
121
235
 
122
236
  ## License
123
237
 
124
- Apache-2.0
238
+ MIT
239
+
@@ -0,0 +1,27 @@
1
+ /**
2
+ * DEX Generator Service
3
+ * Converts .class files to .dex using d8 (Android DEX compiler)
4
+ */
5
+ export interface DexResult {
6
+ success: boolean;
7
+ dexPath: string;
8
+ dexBytes: Buffer | null;
9
+ errors: string[];
10
+ }
11
+ export declare class DexGenerator {
12
+ private static readonly TAG;
13
+ private d8Path;
14
+ /**
15
+ * Find d8 executable in Android SDK
16
+ */
17
+ findD8(): Promise<string | null>;
18
+ /**
19
+ * Convert .class files to a single .dex file
20
+ */
21
+ generateDex(classFiles: string[], outputDir?: string): Promise<DexResult>;
22
+ /**
23
+ * Run a command and return result
24
+ */
25
+ private runCommand;
26
+ }
27
+ //# sourceMappingURL=dex-generator.d.ts.map
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+ /**
3
+ * DEX Generator Service
4
+ * Converts .class files to .dex using d8 (Android DEX compiler)
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.DexGenerator = void 0;
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const os = __importStar(require("os"));
44
+ const child_process_1 = require("child_process");
45
+ const logger_1 = require("../utils/logger");
46
+ class DexGenerator {
47
+ static TAG = 'DexGenerator';
48
+ d8Path = null;
49
+ /**
50
+ * Find d8 executable in Android SDK
51
+ */
52
+ async findD8() {
53
+ if (this.d8Path)
54
+ return this.d8Path;
55
+ // Check multiple locations for Android SDK
56
+ let androidHome = process.env.ANDROID_HOME || process.env.ANDROID_SDK_ROOT;
57
+ // Fallback to common Windows locations
58
+ if (!androidHome) {
59
+ const commonLocations = [
60
+ 'C:\\Android',
61
+ path.join(os.homedir(), 'AppData', 'Local', 'Android', 'Sdk'),
62
+ 'C:\\Users\\Public\\Android\\Sdk',
63
+ ];
64
+ for (const loc of commonLocations) {
65
+ if (fs.existsSync(path.join(loc, 'build-tools'))) {
66
+ androidHome = loc;
67
+ (0, logger_1.log)(`Found Android SDK at: ${loc}`);
68
+ break;
69
+ }
70
+ }
71
+ }
72
+ if (!androidHome) {
73
+ (0, logger_1.error)('ANDROID_HOME or ANDROID_SDK_ROOT not set');
74
+ return null;
75
+ }
76
+ // d8 is in build-tools
77
+ const buildToolsDir = path.join(androidHome, 'build-tools');
78
+ if (!fs.existsSync(buildToolsDir)) {
79
+ (0, logger_1.error)('Android build-tools not found');
80
+ return null;
81
+ }
82
+ // Find latest build-tools version
83
+ const versions = fs.readdirSync(buildToolsDir)
84
+ .filter(v => /^\d+\.\d+\.\d+$/.test(v))
85
+ .sort((a, b) => {
86
+ const aParts = a.split('.').map(Number);
87
+ const bParts = b.split('.').map(Number);
88
+ for (let i = 0; i < 3; i++) {
89
+ if (aParts[i] !== bParts[i])
90
+ return bParts[i] - aParts[i];
91
+ }
92
+ return 0;
93
+ });
94
+ if (versions.length === 0) {
95
+ (0, logger_1.error)('No Android build-tools version found');
96
+ return null;
97
+ }
98
+ const d8Name = os.platform() === 'win32' ? 'd8.bat' : 'd8';
99
+ const d8Path = path.join(buildToolsDir, versions[0], d8Name);
100
+ if (!fs.existsSync(d8Path)) {
101
+ (0, logger_1.error)(`d8 not found at: ${d8Path}`);
102
+ return null;
103
+ }
104
+ this.d8Path = d8Path;
105
+ (0, logger_1.log)(`Found d8 at: ${d8Path} (build-tools ${versions[0]})`);
106
+ return d8Path;
107
+ }
108
+ /**
109
+ * Convert .class files to a single .dex file
110
+ */
111
+ async generateDex(classFiles, outputDir) {
112
+ const d8 = await this.findD8();
113
+ if (!d8) {
114
+ return {
115
+ success: false,
116
+ dexPath: '',
117
+ dexBytes: null,
118
+ errors: ['d8 not found - Android SDK build-tools not installed']
119
+ };
120
+ }
121
+ if (classFiles.length === 0) {
122
+ return {
123
+ success: false,
124
+ dexPath: '',
125
+ dexBytes: null,
126
+ errors: ['No class files provided']
127
+ };
128
+ }
129
+ // Create output directory
130
+ const dexOutputDir = outputDir || path.join(os.tmpdir(), 'jetstart-dex', Date.now().toString());
131
+ fs.mkdirSync(dexOutputDir, { recursive: true });
132
+ (0, logger_1.log)(`Generating DEX from ${classFiles.length} class files...`);
133
+ // Build d8 arguments
134
+ const args = [
135
+ '--output', dexOutputDir,
136
+ '--min-api', '24',
137
+ ...classFiles
138
+ ];
139
+ const result = await this.runCommand(d8, args);
140
+ if (!result.success) {
141
+ return {
142
+ success: false,
143
+ dexPath: '',
144
+ dexBytes: null,
145
+ errors: [result.stderr || 'DEX generation failed']
146
+ };
147
+ }
148
+ // Find generated dex file
149
+ const dexPath = path.join(dexOutputDir, 'classes.dex');
150
+ if (!fs.existsSync(dexPath)) {
151
+ return {
152
+ success: false,
153
+ dexPath: '',
154
+ dexBytes: null,
155
+ errors: ['DEX file not generated']
156
+ };
157
+ }
158
+ const dexBytes = fs.readFileSync(dexPath);
159
+ (0, logger_1.log)(`Generated DEX: ${dexBytes.length} bytes`);
160
+ return {
161
+ success: true,
162
+ dexPath,
163
+ dexBytes,
164
+ errors: []
165
+ };
166
+ }
167
+ /**
168
+ * Run a command and return result
169
+ */
170
+ runCommand(cmd, args) {
171
+ return new Promise((resolve) => {
172
+ const proc = (0, child_process_1.spawn)(cmd, args, {
173
+ shell: os.platform() === 'win32',
174
+ env: process.env
175
+ });
176
+ let stdout = '';
177
+ let stderr = '';
178
+ proc.stdout?.on('data', (data) => {
179
+ stdout += data.toString();
180
+ });
181
+ proc.stderr?.on('data', (data) => {
182
+ stderr += data.toString();
183
+ });
184
+ proc.on('close', (code) => {
185
+ resolve({
186
+ success: code === 0,
187
+ stdout,
188
+ stderr
189
+ });
190
+ });
191
+ proc.on('error', (err) => {
192
+ resolve({
193
+ success: false,
194
+ stdout: '',
195
+ stderr: err.message
196
+ });
197
+ });
198
+ });
199
+ }
200
+ }
201
+ exports.DexGenerator = DexGenerator;
202
+ //# sourceMappingURL=dex-generator.js.map
@@ -13,42 +13,15 @@ export declare class DSLParser {
13
13
  * Parse Kotlin content and extract UI definition
14
14
  */
15
15
  static parseContent(content: string, filePath: string): ParseResult;
16
- /**
17
- * Extract DSL JSON from getDefaultDSL() or similar function (legacy support)
18
- */
19
16
  private static extractDSLFromFunction;
20
17
  /**
21
18
  * Find the main @Composable function in the file
22
19
  */
23
- private static findMainComposable;
24
- /**
25
- * Extract function body handling nested braces
26
- */
27
- private static extractFunctionBody;
28
- /**
29
- * Parse the composable body and extract UI structure
30
- */
31
- private static parseComposableBody;
32
- /**
33
- * Parse a layout element (Column, Row, Box)
34
- */
35
- private static parseLayout;
36
- /**
37
- * Parse modifier chain
38
- */
39
- private static parseModifier;
40
- /**
41
- * Parse children elements (handles multi-line elements)
42
- * Maintains source code order
43
- */
44
- private static parseChildren;
45
- /**
46
- * Extract content within parentheses (handles nesting)
47
- */
48
- private static extractParenthesesContent;
49
20
  /**
50
- * Generate default DSL when parsing fails
21
+ * Find the main @Composable and a library of all others
51
22
  */
23
+ private static extractComposables;
24
+ private static findMatchingBracket;
52
25
  private static generateDefaultDSL;
53
26
  }
54
27
  //# sourceMappingURL=dsl-parser.d.ts.map