@jetstart/core 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.
Files changed (116) hide show
  1. package/.eslintrc.json +6 -0
  2. package/README.md +124 -0
  3. package/dist/build/builder.d.ts +57 -0
  4. package/dist/build/builder.d.ts.map +1 -0
  5. package/dist/build/builder.js +151 -0
  6. package/dist/build/builder.js.map +1 -0
  7. package/dist/build/cache.d.ts +51 -0
  8. package/dist/build/cache.d.ts.map +1 -0
  9. package/dist/build/cache.js +152 -0
  10. package/dist/build/cache.js.map +1 -0
  11. package/dist/build/dsl-parser.d.ts +54 -0
  12. package/dist/build/dsl-parser.d.ts.map +1 -0
  13. package/dist/build/dsl-parser.js +373 -0
  14. package/dist/build/dsl-parser.js.map +1 -0
  15. package/dist/build/dsl-types.d.ts +47 -0
  16. package/dist/build/dsl-types.d.ts.map +1 -0
  17. package/dist/build/dsl-types.js +7 -0
  18. package/dist/build/dsl-types.js.map +1 -0
  19. package/dist/build/gradle-injector.d.ts +14 -0
  20. package/dist/build/gradle-injector.d.ts.map +1 -0
  21. package/dist/build/gradle-injector.js +77 -0
  22. package/dist/build/gradle-injector.js.map +1 -0
  23. package/dist/build/gradle.d.ts +43 -0
  24. package/dist/build/gradle.d.ts.map +1 -0
  25. package/dist/build/gradle.js +281 -0
  26. package/dist/build/gradle.js.map +1 -0
  27. package/dist/build/index.d.ts +10 -0
  28. package/dist/build/index.d.ts.map +1 -0
  29. package/dist/build/index.js +26 -0
  30. package/dist/build/index.js.map +1 -0
  31. package/dist/build/parser.d.ts +12 -0
  32. package/dist/build/parser.d.ts.map +1 -0
  33. package/dist/build/parser.js +71 -0
  34. package/dist/build/parser.js.map +1 -0
  35. package/dist/build/watcher.d.ts +30 -0
  36. package/dist/build/watcher.d.ts.map +1 -0
  37. package/dist/build/watcher.js +120 -0
  38. package/dist/build/watcher.js.map +1 -0
  39. package/dist/index.d.ts +11 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +26 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/server/http.d.ts +12 -0
  44. package/dist/server/http.d.ts.map +1 -0
  45. package/dist/server/http.js +32 -0
  46. package/dist/server/http.js.map +1 -0
  47. package/dist/server/index.d.ts +35 -0
  48. package/dist/server/index.d.ts.map +1 -0
  49. package/dist/server/index.js +262 -0
  50. package/dist/server/index.js.map +1 -0
  51. package/dist/server/middleware.d.ts +7 -0
  52. package/dist/server/middleware.d.ts.map +1 -0
  53. package/dist/server/middleware.js +42 -0
  54. package/dist/server/middleware.js.map +1 -0
  55. package/dist/server/routes.d.ts +7 -0
  56. package/dist/server/routes.d.ts.map +1 -0
  57. package/dist/server/routes.js +104 -0
  58. package/dist/server/routes.js.map +1 -0
  59. package/dist/types/index.d.ts +20 -0
  60. package/dist/types/index.d.ts.map +1 -0
  61. package/dist/types/index.js +6 -0
  62. package/dist/types/index.js.map +1 -0
  63. package/dist/utils/index.d.ts +7 -0
  64. package/dist/utils/index.d.ts.map +1 -0
  65. package/dist/utils/index.js +23 -0
  66. package/dist/utils/index.js.map +1 -0
  67. package/dist/utils/logger.d.ts +10 -0
  68. package/dist/utils/logger.d.ts.map +1 -0
  69. package/dist/utils/logger.js +33 -0
  70. package/dist/utils/logger.js.map +1 -0
  71. package/dist/utils/qr.d.ts +8 -0
  72. package/dist/utils/qr.d.ts.map +1 -0
  73. package/dist/utils/qr.js +48 -0
  74. package/dist/utils/qr.js.map +1 -0
  75. package/dist/utils/session.d.ts +18 -0
  76. package/dist/utils/session.d.ts.map +1 -0
  77. package/dist/utils/session.js +49 -0
  78. package/dist/utils/session.js.map +1 -0
  79. package/dist/websocket/handler.d.ts +25 -0
  80. package/dist/websocket/handler.d.ts.map +1 -0
  81. package/dist/websocket/handler.js +126 -0
  82. package/dist/websocket/handler.js.map +1 -0
  83. package/dist/websocket/index.d.ts +18 -0
  84. package/dist/websocket/index.d.ts.map +1 -0
  85. package/dist/websocket/index.js +40 -0
  86. package/dist/websocket/index.js.map +1 -0
  87. package/dist/websocket/manager.d.ts +16 -0
  88. package/dist/websocket/manager.d.ts.map +1 -0
  89. package/dist/websocket/manager.js +58 -0
  90. package/dist/websocket/manager.js.map +1 -0
  91. package/package.json +78 -0
  92. package/src/build/builder.ts +192 -0
  93. package/src/build/cache.ts +144 -0
  94. package/src/build/dsl-parser.ts +382 -0
  95. package/src/build/dsl-types.ts +50 -0
  96. package/src/build/gradle-injector.ts +64 -0
  97. package/src/build/gradle.ts +305 -0
  98. package/src/build/index.ts +10 -0
  99. package/src/build/parser.ts +75 -0
  100. package/src/build/watcher.ts +103 -0
  101. package/src/index.ts +20 -0
  102. package/src/server/http.ts +38 -0
  103. package/src/server/index.ts +272 -0
  104. package/src/server/middleware.ts +43 -0
  105. package/src/server/routes.ts +116 -0
  106. package/src/types/index.ts +21 -0
  107. package/src/utils/index.ts +7 -0
  108. package/src/utils/logger.ts +28 -0
  109. package/src/utils/qr.ts +46 -0
  110. package/src/utils/session.ts +58 -0
  111. package/src/websocket/handler.ts +150 -0
  112. package/src/websocket/index.ts +56 -0
  113. package/src/websocket/manager.ts +63 -0
  114. package/tests/build.test.ts +13 -0
  115. package/tests/server.test.ts +13 -0
  116. package/tsconfig.json +25 -0
@@ -0,0 +1,150 @@
1
+ /**
2
+ * WebSocket Message Handler
3
+ * Processes incoming WebSocket messages
4
+ */
5
+
6
+ import {
7
+ WSMessage,
8
+ ClientMessage,
9
+ CoreConnectedMessage,
10
+ CoreBuildStartMessage,
11
+ CoreBuildCompleteMessage,
12
+ CoreUIUpdateMessage,
13
+ } from '@jetstart/shared';
14
+ import { ConnectionManager } from './manager';
15
+ import { log, error as logError } from '../utils/logger';
16
+
17
+ export class WebSocketHandler {
18
+ private onClientConnected?: (sessionId: string) => void;
19
+
20
+ constructor(
21
+ private connectionManager: ConnectionManager,
22
+ options?: { onClientConnected?: (sessionId: string) => void }
23
+ ) {
24
+ this.onClientConnected = options?.onClientConnected;
25
+ }
26
+
27
+ handleMessage(clientId: string, data: Buffer): void {
28
+ try {
29
+ const message: WSMessage = JSON.parse(data.toString());
30
+ log(`Received message from ${clientId}: ${message.type}`);
31
+
32
+ // Route message based on type
33
+ if (this.isClientMessage(message)) {
34
+ this.handleClientMessage(clientId, message);
35
+ }
36
+
37
+ } catch (err: any) {
38
+ logError(`Failed to parse message from ${clientId}: ${err.message}`);
39
+ }
40
+ }
41
+
42
+ private isClientMessage(message: WSMessage): message is ClientMessage {
43
+ return message.type.startsWith('client:');
44
+ }
45
+
46
+ private handleClientMessage(clientId: string, message: ClientMessage): void {
47
+ switch (message.type) {
48
+ case 'client:connect':
49
+ this.handleConnect(clientId, message);
50
+ break;
51
+ case 'client:status':
52
+ log(`Client ${clientId} status: ${message.status}`);
53
+ break;
54
+ case 'client:log':
55
+ // Forward to logs service
56
+ break;
57
+ case 'client:heartbeat':
58
+ // Update last activity
59
+ break;
60
+ case 'client:disconnect':
61
+ this.handleDisconnect(clientId, message);
62
+ break;
63
+ }
64
+ }
65
+
66
+ private handleConnect(clientId: string, message: ClientMessage & { type: 'client:connect' }): void {
67
+ log(`Client connecting with session: ${message.sessionId}`);
68
+
69
+ // Send connected confirmation
70
+ const response: CoreConnectedMessage = {
71
+ type: 'core:connected',
72
+ timestamp: Date.now(),
73
+ sessionId: message.sessionId,
74
+ projectName: 'DemoProject', // In real implementation, get from session
75
+ };
76
+
77
+ this.connectionManager.sendToClient(clientId, response);
78
+
79
+ // Trigger initial build for the client
80
+ if (this.onClientConnected) {
81
+ log(`Triggering initial build for session: ${message.sessionId}`);
82
+ this.onClientConnected(message.sessionId);
83
+ }
84
+ }
85
+
86
+ private handleDisconnect(clientId: string, message: ClientMessage & { type: 'client:disconnect' }): void {
87
+ log(`Client disconnecting: ${message.reason || 'No reason provided'}`);
88
+ }
89
+
90
+ // Send build notifications
91
+ sendBuildStart(sessionId: string): void {
92
+ const message: CoreBuildStartMessage = {
93
+ type: 'core:build-start',
94
+ timestamp: Date.now(),
95
+ sessionId,
96
+ };
97
+
98
+ this.connectionManager.broadcast(message);
99
+ }
100
+
101
+ sendBuildComplete(sessionId: string, apkUrl: string): void {
102
+ const message: CoreBuildCompleteMessage = {
103
+ type: 'core:build-complete',
104
+ timestamp: Date.now(),
105
+ sessionId,
106
+ apkInfo: {
107
+ path: '/path/to/app.apk',
108
+ size: 5242880,
109
+ hash: 'abc123',
110
+ versionCode: 1,
111
+ versionName: '1.0.0',
112
+ minSdkVersion: 24,
113
+ targetSdkVersion: 34,
114
+ applicationId: 'com.example.app',
115
+ },
116
+ downloadUrl: apkUrl,
117
+ };
118
+
119
+ this.connectionManager.broadcast(message);
120
+ }
121
+
122
+ /**
123
+ * Send UI update (DSL-based hot reload)
124
+ */
125
+ sendUIUpdate(sessionId: string, dslContent: string, screens?: string[]): void {
126
+ const message: CoreUIUpdateMessage = {
127
+ type: 'core:ui-update',
128
+ timestamp: Date.now(),
129
+ sessionId,
130
+ dslContent,
131
+ screens,
132
+ hash: this.generateHash(dslContent),
133
+ };
134
+
135
+ log(`Sending UI update: ${dslContent.length} bytes`);
136
+ log(`DSL Content: ${dslContent}`);
137
+ this.connectionManager.broadcast(message);
138
+ }
139
+
140
+ private generateHash(content: string): string {
141
+ // Simple hash for caching (in production, use crypto.createHash)
142
+ let hash = 0;
143
+ for (let i = 0; i < content.length; i++) {
144
+ const char = content.charCodeAt(i);
145
+ hash = ((hash << 5) - hash) + char;
146
+ hash = hash & hash; // Convert to 32bit integer
147
+ }
148
+ return hash.toString(16);
149
+ }
150
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * WebSocket Server
3
+ * Real-time communication with clients
4
+ */
5
+
6
+ import { WebSocketServer, WebSocket } from 'ws';
7
+ import { Server } from 'http';
8
+ import { WebSocketHandler } from './handler';
9
+ import { ConnectionManager } from './manager';
10
+ import { log } from '../utils/logger';
11
+
12
+ export interface WebSocketConfig {
13
+ port: number;
14
+ server?: Server;
15
+ onClientConnected?: (sessionId: string) => void;
16
+ }
17
+
18
+ export interface WebSocketServerResult {
19
+ server: WebSocketServer;
20
+ handler: WebSocketHandler;
21
+ }
22
+
23
+ export async function createWebSocketServer(config: WebSocketConfig): Promise<WebSocketServerResult> {
24
+ const wss = new WebSocketServer({
25
+ port: config.port,
26
+ });
27
+
28
+ const connectionManager = new ConnectionManager();
29
+ const handler = new WebSocketHandler(connectionManager, {
30
+ onClientConnected: config.onClientConnected,
31
+ });
32
+
33
+ wss.on('connection', (ws: WebSocket, _request) => {
34
+ const clientId = connectionManager.addConnection(ws);
35
+ log(`WebSocket client connected: ${clientId}`);
36
+
37
+ // Handle messages
38
+ ws.on('message', (data: Buffer) => {
39
+ handler.handleMessage(clientId, data);
40
+ });
41
+
42
+ // Handle disconnection
43
+ ws.on('close', () => {
44
+ log(`WebSocket client disconnected: ${clientId}`);
45
+ connectionManager.removeConnection(clientId);
46
+ });
47
+
48
+ // Handle errors
49
+ ws.on('error', (err: Error) => {
50
+ console.error(`WebSocket error for ${clientId}:`, err.message);
51
+ });
52
+ });
53
+
54
+ log(`WebSocket server listening on port ${config.port}`);
55
+ return { server: wss, handler };
56
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Connection Manager
3
+ * Manages WebSocket connections
4
+ */
5
+
6
+ import { WebSocket } from 'ws';
7
+ import { v4 as uuidv4 } from 'uuid';
8
+ import { CoreMessage } from '@jetstart/shared';
9
+
10
+ export class ConnectionManager {
11
+ private connections: Map<string, WebSocket> = new Map();
12
+
13
+ addConnection(ws: WebSocket): string {
14
+ const id = uuidv4();
15
+ this.connections.set(id, ws);
16
+ return id;
17
+ }
18
+
19
+ removeConnection(id: string): void {
20
+ this.connections.delete(id);
21
+ }
22
+
23
+ getConnection(id: string): WebSocket | undefined {
24
+ return this.connections.get(id);
25
+ }
26
+
27
+ sendToClient(clientId: string, message: CoreMessage): boolean {
28
+ const ws = this.connections.get(clientId);
29
+
30
+ if (!ws || ws.readyState !== WebSocket.OPEN) {
31
+ return false;
32
+ }
33
+
34
+ try {
35
+ ws.send(JSON.stringify(message));
36
+ return true;
37
+ } catch (err) {
38
+ console.error(`Failed to send message to ${clientId}:`, err);
39
+ return false;
40
+ }
41
+ }
42
+
43
+ broadcast(message: CoreMessage): void {
44
+ const data = JSON.stringify(message);
45
+ const connectionCount = Array.from(this.connections.values()).filter(ws => ws.readyState === WebSocket.OPEN).length;
46
+ console.log(`[ConnectionManager] Broadcasting ${message.type} to ${connectionCount} connected clients`);
47
+
48
+ this.connections.forEach((ws, clientId) => {
49
+ if (ws.readyState === WebSocket.OPEN) {
50
+ try {
51
+ ws.send(data);
52
+ console.log(`[ConnectionManager] Sent ${message.type} to client ${clientId}`);
53
+ } catch (err) {
54
+ console.error(`Failed to broadcast to ${clientId}:`, err);
55
+ }
56
+ }
57
+ });
58
+ }
59
+
60
+ getConnectionCount(): number {
61
+ return this.connections.size;
62
+ }
63
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Tests for build system
3
+ */
4
+
5
+ describe('Build System', () => {
6
+ it('should compile Kotlin project', () => {
7
+ expect(true).toBe(true);
8
+ });
9
+
10
+ it('should cache build results', () => {
11
+ expect(true).toBe(true);
12
+ });
13
+ });
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Tests for HTTP server
3
+ */
4
+
5
+ describe('HTTP Server', () => {
6
+ it('should start server on specified port', () => {
7
+ expect(true).toBe(true);
8
+ });
9
+
10
+ it('should handle health check endpoint', () => {
11
+ expect(true).toBe(true);
12
+ });
13
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "commonjs",
5
+ "lib": ["ES2022"],
6
+ "moduleResolution": "node",
7
+ "esModuleInterop": true,
8
+ "allowSyntheticDefaultImports": true,
9
+ "strict": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "resolveJsonModule": true,
13
+ "declaration": true,
14
+ "declarationMap": true,
15
+ "sourceMap": true,
16
+ "composite": true,
17
+ "outDir": "./dist",
18
+ "rootDir": "./src"
19
+ },
20
+ "references": [
21
+ { "path": "../shared" }
22
+ ],
23
+ "include": ["src/**/*"],
24
+ "exclude": ["node_modules", "dist", "tests"]
25
+ }