Skip to content
This repository was archived by the owner on Oct 18, 2024. It is now read-only.

Cleanup the bootstrapping file to make it easier to interpret #31

Merged
merged 14 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
228 changes: 135 additions & 93 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,137 +11,179 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
const electron_1 = require("electron");
const electron_updater_1 = require("electron-updater");
const state_1 = __importDefault(require("./server/state"));
const utils_1 = require("@electron-toolkit/utils");
const server_1 = require("./server");
const utils_2 = require("./server/utils");
const electron_1 = require("electron");
const path_1 = require("path");
const ps_node_1 = __importDefault(require("ps-node"));
let phpProcesses = [];
let websocketProcess;
let schedulerInterval;
const killChildProcesses = () => {
let processes = [
...phpProcesses,
websocketProcess,
].filter((p) => p !== undefined);
processes.forEach((process) => {
try {
ps_node_1.default.kill(process.pid);
}
catch (err) {
console.error(err);
}
});
};
class NativePHP {
constructor() {
this.processes = [];
this.schedulerInterval = undefined;
}
bootstrap(app, icon, phpBinary, cert) {
require('@electron/remote/main').initialize();
require("@electron/remote/main").initialize();
state_1.default.icon = icon;
state_1.default.php = phpBinary;
state_1.default.caCert = cert;
this.bootstrapApp(app);
this.addEventListeners(app);
this.addTerminateListeners(app);
}
addEventListeners(app) {
app.on('open-url', (event, url) => {
(0, utils_2.notifyLaravel)('events', {
event: '\\Native\\Laravel\\Events\\App\\OpenedFromURL',
payload: [url]
app.on("open-url", (event, url) => {
(0, utils_2.notifyLaravel)("events", {
event: "\\Native\\Laravel\\Events\\App\\OpenedFromURL",
payload: [url],
});
});
app.on('open-file', (event, path) => {
(0, utils_2.notifyLaravel)('events', {
event: '\\Native\\Laravel\\Events\\App\\OpenFile',
payload: [path]
app.on("open-file", (event, path) => {
(0, utils_2.notifyLaravel)("events", {
event: "\\Native\\Laravel\\Events\\App\\OpenFile",
payload: [path],
});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
}
addTerminateListeners(app) {
app.on('before-quit', (e) => {
if (schedulerInterval) {
clearInterval(schedulerInterval);
app.on("before-quit", () => {
if (this.schedulerInterval) {
clearInterval(this.schedulerInterval);
}
this.killChildProcesses();
});
app.on("browser-window-created", (_, window) => {
utils_1.optimizer.watchWindowShortcuts(window);
});
app.on("activate", function (event, hasVisibleWindows) {
if (!hasVisibleWindows) {
(0, utils_2.notifyLaravel)("booted");
}
killChildProcesses();
event.preventDefault();
});
}
bootstrapApp(app) {
let nativePHPConfig = {};
(0, server_1.retrieveNativePHPConfig)().then((result) => {
return __awaiter(this, void 0, void 0, function* () {
yield app.whenReady();
const config = yield this.loadConfig();
this.setDockIcon();
this.setAppUserModelId(config);
this.setDeepLinkHandler(config);
this.startAutoUpdater(config);
yield this.startElectronApi();
state_1.default.phpIni = yield this.loadPhpIni();
yield this.startPhpApp();
yield this.startQueueWorker();
yield this.startWebsockets();
this.startScheduler();
yield (0, utils_2.notifyLaravel)("booted");
});
}
loadConfig() {
return __awaiter(this, void 0, void 0, function* () {
let config = {};
try {
nativePHPConfig = JSON.parse(result.stdout);
const result = yield (0, server_1.retrieveNativePHPConfig)();
config = JSON.parse(result.stdout);
}
catch (e) {
console.error(e);
catch (error) {
console.error(error);
}
}).catch((err) => {
console.error(err);
}).finally(() => {
this.setupApp(nativePHPConfig);
return config;
});
}
setupApp(nativePHPConfig) {
electron_1.app.whenReady().then(() => __awaiter(this, void 0, void 0, function* () {
var _a;
if (process.platform === 'darwin' && process.env.NODE_ENV === 'development') {
electron_1.app.dock.setIcon(state_1.default.icon);
setDockIcon() {
if (process.platform === "darwin" &&
process.env.NODE_ENV === "development") {
electron_1.app.dock.setIcon(state_1.default.icon);
}
}
setAppUserModelId(config) {
utils_1.electronApp.setAppUserModelId(config === null || config === void 0 ? void 0 : config.app_id);
}
setDeepLinkHandler(config) {
const deepLinkProtocol = config === null || config === void 0 ? void 0 : config.deeplink_scheme;
if (deepLinkProtocol) {
if (process.defaultApp) {
if (process.argv.length >= 2) {
electron_1.app.setAsDefaultProtocolClient(deepLinkProtocol, process.execPath, [
(0, path_1.resolve)(process.argv[1]),
]);
}
}
electron_1.app.on('browser-window-created', (_, window) => {
utils_1.optimizer.watchWindowShortcuts(window);
});
let phpIniSettings = {};
else {
electron_1.app.setAsDefaultProtocolClient(deepLinkProtocol);
}
}
}
startAutoUpdater(config) {
var _a;
if (((_a = config === null || config === void 0 ? void 0 : config.updater) === null || _a === void 0 ? void 0 : _a.enabled) === true) {
electron_updater_1.autoUpdater.checkForUpdatesAndNotify();
}
}
startElectronApi() {
return __awaiter(this, void 0, void 0, function* () {
const electronApi = yield (0, server_1.startAPI)();
state_1.default.electronApiPort = electronApi.port;
console.log("Electron API server started on port", electronApi.port);
});
}
loadPhpIni() {
return __awaiter(this, void 0, void 0, function* () {
let config = {};
try {
let { stdout } = yield (0, server_1.retrievePhpIniSettings)();
phpIniSettings = JSON.parse(stdout);
const result = yield (0, server_1.retrievePhpIniSettings)();
config = JSON.parse(result.stdout);
}
catch (e) {
console.error(e);
catch (error) {
console.error(error);
}
utils_1.electronApp.setAppUserModelId(nativePHPConfig === null || nativePHPConfig === void 0 ? void 0 : nativePHPConfig.app_id);
const deepLinkProtocol = nativePHPConfig === null || nativePHPConfig === void 0 ? void 0 : nativePHPConfig.deeplink_scheme;
if (deepLinkProtocol) {
if (process.defaultApp) {
if (process.argv.length >= 2) {
electron_1.app.setAsDefaultProtocolClient(deepLinkProtocol, process.execPath, [(0, path_1.resolve)(process.argv[1])]);
}
}
else {
electron_1.app.setAsDefaultProtocolClient(deepLinkProtocol);
}
return config;
});
}
startPhpApp() {
return __awaiter(this, void 0, void 0, function* () {
this.processes.push(yield (0, server_1.startPhpApp)());
});
}
startQueueWorker() {
return __awaiter(this, void 0, void 0, function* () {
this.processes.push(yield (0, server_1.startQueue)());
});
}
startWebsockets() {
return __awaiter(this, void 0, void 0, function* () {
this.processes.push(yield (0, server_1.startWebsockets)());
});
}
startScheduler() {
const now = new Date();
const delay = (60 - now.getSeconds()) * 1000 + (1000 - now.getMilliseconds());
setTimeout(() => {
console.log("Running scheduler...");
(0, server_1.runScheduler)();
this.schedulerInterval = setInterval(() => {
console.log("Running scheduler...");
(0, server_1.runScheduler)();
}, 60 * 1000);
}, delay);
}
killChildProcesses() {
this.processes
.filter((p) => p !== undefined)
.forEach((process) => {
try {
ps_node_1.default.kill(process.pid);
}
const apiPort = yield (0, server_1.startAPI)();
console.log('API server started on port', apiPort.port);
phpProcesses = yield (0, server_1.servePhpApp)(apiPort.port, phpIniSettings);
websocketProcess = (0, server_1.serveWebsockets)();
yield (0, utils_2.notifyLaravel)('booted');
if (((_a = nativePHPConfig === null || nativePHPConfig === void 0 ? void 0 : nativePHPConfig.updater) === null || _a === void 0 ? void 0 : _a.enabled) === true) {
electron_updater_1.autoUpdater.checkForUpdatesAndNotify();
catch (err) {
console.error(err);
}
let now = new Date();
let delay = (60 - now.getSeconds()) * 1000 + (1000 - now.getMilliseconds());
setTimeout(() => {
console.log("Running scheduler...");
(0, server_1.runScheduler)(apiPort.port, phpIniSettings);
schedulerInterval = setInterval(() => {
console.log("Running scheduler...");
(0, server_1.runScheduler)(apiPort.port, phpIniSettings);
}, 60 * 1000);
}, delay);
electron_1.app.on('activate', function (event, hasVisibleWindows) {
if (!hasVisibleWindows) {
(0, utils_2.notifyLaravel)('booted');
}
event.preventDefault();
});
}));
});
}
}
module.exports = new NativePHP();
30 changes: 15 additions & 15 deletions dist/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,37 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.retrievePhpIniSettings = exports.retrieveNativePHPConfig = exports.serveWebsockets = exports.startAPI = exports.startQueue = exports.runScheduler = exports.servePhpApp = void 0;
exports.retrievePhpIniSettings = exports.retrieveNativePHPConfig = exports.startWebsockets = exports.startAPI = exports.runScheduler = exports.startQueue = exports.startPhpApp = void 0;
const websockets_1 = __importDefault(require("./websockets"));
exports.serveWebsockets = websockets_1.default;
exports.startWebsockets = websockets_1.default;
const api_1 = __importDefault(require("./api"));
const php_1 = require("./php");
Object.defineProperty(exports, "retrieveNativePHPConfig", { enumerable: true, get: function () { return php_1.retrieveNativePHPConfig; } });
Object.defineProperty(exports, "retrievePhpIniSettings", { enumerable: true, get: function () { return php_1.retrievePhpIniSettings; } });
const utils_1 = require("./utils");
const state_1 = __importDefault(require("./state"));
function servePhpApp(apiPort, phpIniSettings) {
function startPhpApp() {
return __awaiter(this, void 0, void 0, function* () {
const processes = [];
const result = yield (0, php_1.serveApp)(state_1.default.randomSecret, apiPort, phpIniSettings);
processes.push(result.process);
processes.push((0, php_1.startQueueWorker)(state_1.default.randomSecret, apiPort, phpIniSettings));
const result = yield (0, php_1.serveApp)(state_1.default.randomSecret, state_1.default.electronApiPort, state_1.default.phpIni);
state_1.default.phpPort = result.port;
yield (0, utils_1.appendCookie)();
return processes;
return result.process;
});
}
exports.servePhpApp = servePhpApp;
function runScheduler(apiPort, phpIniSettings) {
(0, php_1.startScheduler)(state_1.default.randomSecret, apiPort, phpIniSettings);
}
exports.runScheduler = runScheduler;
function startQueue(apiPort, phpIniSettings) {
exports.startPhpApp = startPhpApp;
function startQueue() {
if (!process.env.NATIVE_PHP_SKIP_QUEUE) {
return (0, php_1.startQueueWorker)(state_1.default.randomSecret, apiPort, phpIniSettings);
return (0, php_1.startQueueWorker)(state_1.default.randomSecret, state_1.default.electronApiPort, state_1.default.phpIni);
}
else {
return undefined;
}
}
exports.startQueue = startQueue;
function runScheduler() {
(0, php_1.startScheduler)(state_1.default.randomSecret, state_1.default.electronApiPort, state_1.default.phpIni);
}
exports.runScheduler = runScheduler;
function startAPI() {
return (0, api_1.default)(state_1.default.randomSecret);
}
Expand Down
21 changes: 11 additions & 10 deletions dist/server/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,38 @@ const electron_store_1 = __importDefault(require("electron-store"));
const utils_1 = require("./utils");
const settingsStore = new electron_store_1.default();
settingsStore.onDidAnyChange((newValue, oldValue) => {
const changedKey = Object.keys(newValue).find(key => newValue[key] !== oldValue[key]);
const changedKey = Object.keys(newValue).find((key) => newValue[key] !== oldValue[key]);
if (changedKey) {
(0, utils_1.notifyLaravel)('events', {
event: 'Native\\Laravel\\Events\\Settings\\SettingChanged',
(0, utils_1.notifyLaravel)("events", {
event: "Native\\Laravel\\Events\\Settings\\SettingChanged",
payload: {
key: changedKey,
value: newValue[changedKey] || null
}
value: newValue[changedKey] || null,
},
});
}
});
function generateRandomString(length) {
let result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = "";
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
const charactersLength = characters.length;
for (let i = 0; i < length; i += 1) {
result += characters.charAt(Math.floor(Math.random() *
charactersLength));
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
exports.default = {
electronApiPort: null,
activeMenuBar: null,
php: null,
phpPort: null,
phpIni: null,
caCert: null,
icon: null,
store: settingsStore,
randomSecret: generateRandomString(32),
windows: {},
findWindow(id) {
return this.windows[id] || null;
}
},
};
14 changes: 6 additions & 8 deletions dist/server/websockets.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@ const path_1 = require("path");
const child_process_1 = require("child_process");
const php_1 = require("./php");
const state_1 = __importDefault(require("./state"));
function serveWebsockets() {
if (!(0, fs_1.existsSync)((0, path_1.join)((0, php_1.getAppPath)(), 'vendor', 'beyondcode', 'laravel-websockets'))) {
function startWebsockets() {
if (!(0, fs_1.existsSync)((0, path_1.join)((0, php_1.getAppPath)(), "vendor", "beyondcode", "laravel-websockets"))) {
return;
}
const phpServer = (0, child_process_1.spawn)(state_1.default.php, ["artisan", "websockets:serve"], {
cwd: (0, php_1.getAppPath)()
});
phpServer.stdout.on("data", (data) => {
});
phpServer.stderr.on("data", (data) => {
cwd: (0, php_1.getAppPath)(),
});
phpServer.stdout.on("data", (data) => { });
phpServer.stderr.on("data", (data) => { });
return phpServer;
}
exports.default = serveWebsockets;
exports.default = startWebsockets;
Loading