lively-electron 0.1.1 → 0.1.2
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/bin/lively-electron +5 -1
- data/bin/lively-electron-server +1 -1
- data/lib/lively/electron/version.rb +1 -1
- data/src/main.js +134 -134
- data.tar.gz.sig +0 -0
- metadata +1 -1
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 248f9a41919d7b26d78d41b7a137b839061ad3a1ac721622d0f348d645e572a3
|
4
|
+
data.tar.gz: 74354a3a3a0da8efc6ea18fa707618f98643585b2c606d77bb2ce2d7d572b9e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94189c32f5843bb3dbdab9a6bbbfbb39c141a0cbb1f9cdbdfd0690049fbe06c75956789de5cd3cb8a63f892a792cb2556001c2f332e856545da11e047702879d
|
7
|
+
data.tar.gz: 7ed9041b2a731fef4fa215732b4c5cbf3136f0a39cd1e4d77e120e3ad96e5ce9e111775e22052bdea087b481b3bbae407c3b4dc148ff8799ae505cf12a878de5
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/bin/lively-electron
CHANGED
@@ -8,5 +8,9 @@ if development_mode
|
|
8
8
|
ENV["CONSOLE_LEVEL"] = "debug"
|
9
9
|
end
|
10
10
|
|
11
|
+
electron_path = ENV.fetch("ELECTRON") do
|
12
|
+
`npx which electron`.strip
|
13
|
+
end
|
14
|
+
|
11
15
|
main_js = File.join(__dir__, "..", "src", "main.js")
|
12
|
-
Process.exec(
|
16
|
+
Process.exec(electron_path, main_js, *ARGV)
|
data/bin/lively-electron-server
CHANGED
data/src/main.js
CHANGED
@@ -1,155 +1,155 @@
|
|
1
1
|
const {app, BrowserWindow, ipcMain} = require('electron');
|
2
|
-
const {spawn} = require('child_process');
|
2
|
+
const {spawn, spawnSync} = require('child_process');
|
3
3
|
const http = require('http');
|
4
4
|
const net = require('net');
|
5
5
|
const path = require('path');
|
6
6
|
const fs = require('fs');
|
7
7
|
|
8
8
|
class LivelyElectronApp {
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
9
|
+
constructor() {
|
10
|
+
this.rubyProcess = null;
|
11
|
+
this.mainWindow = null;
|
12
|
+
this.serverUrl = null;
|
13
|
+
|
14
|
+
// Store the working directory (should be preserved by direct CLI)
|
15
|
+
this.originalCwd = process.cwd();
|
16
|
+
console.log('💾 Working directory:', this.originalCwd);
|
17
|
+
}
|
18
|
+
|
19
|
+
isDevelopment() {
|
20
|
+
const variant = process.env.LIVELY_VARIANT || process.env.VARIANT;
|
21
|
+
return variant === "development";
|
22
|
+
}
|
23
|
+
|
24
|
+
async start() {
|
25
|
+
try {
|
26
|
+
// 1. Start Ruby Lively server on TCP localhost
|
27
|
+
await this.startLivelyServer();
|
28
|
+
|
29
|
+
// 2. Create Electron window (connects directly to Ruby server)
|
30
|
+
await this.createWindow();
|
31
|
+
|
32
|
+
console.log(`Lively Electron started - Ruby server: ${this.serverUrl}`);
|
33
|
+
} catch (error) {
|
34
|
+
console.error('Failed to start Lively Electron:', error);
|
35
|
+
app.quit();
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
async startLivelyServer() {
|
40
|
+
return new Promise((resolve, reject) => {
|
41
|
+
// Forward all CLI args to the Ruby server; let the Ruby script decide the application file
|
42
|
+
const args = process.argv.slice(2);
|
43
|
+
|
44
|
+
// Create server and let it bind+listen, then pass handle to child
|
45
|
+
const server = net.createServer();
|
46
|
+
server.listen(0, '127.0.0.1', () => {
|
47
|
+
const port = server.address().port;
|
48
|
+
this.serverUrl = `http://localhost:${port}`;
|
49
|
+
|
50
|
+
const fd = server._handle.fd;
|
51
|
+
|
52
|
+
// Start Ruby process with FD passed via stdio and forward all CLI args
|
53
|
+
const livelyElectronScript = path.join(__dirname, '..', 'bin', 'lively-electron-server');
|
54
|
+
const childArgs = args.slice();
|
55
|
+
|
56
|
+
const child = spawn(livelyElectronScript, childArgs, {
|
57
|
+
stdio: [
|
58
|
+
'inherit', // stdin
|
59
|
+
'inherit', // stdout
|
60
|
+
'inherit', // stderr
|
61
|
+
fd // Pass socket FD as stdio[3]
|
62
|
+
],
|
63
|
+
env: {
|
64
|
+
...process.env,
|
65
|
+
LIVELY_SERVER_DESCRIPTOR: '3' // Tell child it's on FD 3
|
66
|
+
}
|
67
|
+
});
|
68
|
+
|
69
|
+
child.on('spawn', () => {
|
70
|
+
this.rubyProcess = child;
|
71
|
+
server.close((error) => {
|
72
|
+
if (error) {
|
73
|
+
reject(error);
|
74
|
+
} else {
|
75
|
+
console.log(`✅ Ruby server should be ready: ${this.serverUrl}`);
|
76
|
+
resolve();
|
77
|
+
}
|
78
|
+
});
|
79
|
+
});
|
80
|
+
|
81
|
+
child.on('error', (error) => {
|
82
|
+
server.close();
|
83
|
+
console.error('Failed to spawn Ruby process:', error);
|
84
|
+
reject(error);
|
85
|
+
});
|
86
|
+
|
87
|
+
child.on('close', (code) => {
|
88
|
+
this.rubyProcess = null;
|
89
|
+
console.log(`Ruby process exited with code ${code}`);
|
90
|
+
if (code !== 0) {
|
91
|
+
reject(new Error(`Ruby process failed with code ${code}`));
|
92
|
+
}
|
93
|
+
});
|
94
|
+
});
|
95
|
+
});
|
96
|
+
}
|
97
|
+
|
98
|
+
async createWindow() {
|
99
|
+
this.mainWindow = new BrowserWindow({
|
100
|
+
width: 1200,
|
101
|
+
height: 800,
|
102
|
+
webPreferences: {
|
103
|
+
nodeIntegration: false,
|
104
|
+
contextIsolation: true,
|
105
|
+
enableRemoteModule: false
|
106
|
+
},
|
107
|
+
titleBarStyle: 'hiddenInset'
|
108
|
+
});
|
109
|
+
|
110
|
+
// Load the Lively app directly
|
111
|
+
await this.mainWindow.loadURL(this.serverUrl);
|
112
|
+
|
113
|
+
// Open DevTools in development mode
|
114
|
+
if (this.isDevelopment()) {
|
115
|
+
this.mainWindow.webContents.openDevTools();
|
116
|
+
}
|
117
|
+
|
118
|
+
this.mainWindow.on('closed', () => {
|
119
|
+
this.cleanup();
|
120
|
+
});
|
121
|
+
}
|
122
|
+
|
123
|
+
cleanup() {
|
124
|
+
if (this.rubyProcess) {
|
125
|
+
this.rubyProcess.kill();
|
126
|
+
}
|
127
|
+
}
|
128
128
|
}
|
129
129
|
|
130
130
|
// Electron app lifecycle
|
131
131
|
app.whenReady().then(() => {
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
132
|
+
console.log('Electron ready, starting Lively app...');
|
133
|
+
const livelyApp = new LivelyElectronApp();
|
134
|
+
livelyApp.start().catch(error => {
|
135
|
+
console.error('Failed to start Lively app:', error);
|
136
|
+
app.quit();
|
137
|
+
});
|
138
138
|
});
|
139
139
|
|
140
140
|
app.on('window-all-closed', () => {
|
141
|
-
|
142
|
-
|
143
|
-
|
141
|
+
if (process.platform !== 'darwin') {
|
142
|
+
app.quit();
|
143
|
+
}
|
144
144
|
});
|
145
145
|
|
146
146
|
app.on('activate', () => {
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
147
|
+
if (BrowserWindow.getAllWindows().length === 0) {
|
148
|
+
const livelyApp = new LivelyElectronApp();
|
149
|
+
livelyApp.start();
|
150
|
+
}
|
151
151
|
});
|
152
152
|
|
153
153
|
app.on('before-quit', () => {
|
154
|
-
|
154
|
+
// Cleanup will be handled by window close event
|
155
155
|
});
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
metadata.gz.sig
CHANGED
Binary file
|