Skip to content

Commit 0384a6a

Browse files
committed
feat: phNode, node inspector, phoenix node fs integration
1 parent 14cd47e commit 0384a6a

File tree

17 files changed

+306
-21
lines changed

17 files changed

+306
-21
lines changed

.eslintrc.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,11 @@ module.exports = {
100100
"blockBindings": true,
101101
"classes": true
102102
}
103-
}
103+
},
104+
"overrides": [{
105+
"files": ["src-node/**/*.js", "src-node/*.js"],
106+
"env": {
107+
"node": true
108+
}
109+
}]
104110
};

package-lock.json

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
"@floating-ui/dom": "^0.5.4",
8888
"@fortawesome/fontawesome-free": "^6.1.2",
8989
"@highlightjs/cdn-assets": "^11.5.1",
90-
"@phcode/fs": "^2.0.5",
90+
"@phcode/fs": "^2.0.6",
9191
"@pixelbrackets/gfm-stylesheet": "^1.1.0",
9292
"@prettier/plugin-php": "0.18.9",
9393
"bootstrap": "^5.1.3",

src-node/index.js

Lines changed: 141 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,141 @@
1-
console.log("hello world");
1+
/*
2+
* GNU AGPL-3.0 License
3+
*
4+
* Copyright (c) 2021 - present core.ai . All rights reserved.
5+
* Original work Copyright (c) 2014 - 2021 Adobe Systems Incorporated. All rights reserved.
6+
*
7+
* This program is free software: you can redistribute it and/or modify it
8+
* under the terms of the GNU Affero General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful, but WITHOUT
13+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
15+
* for more details.
16+
*
17+
* You should have received a copy of the GNU Affero General Public License
18+
* along with this program. If not, see https://opensource.org/licenses/AGPL-3.0.
19+
*
20+
*/
21+
22+
const readline = require('readline');
23+
const http = require('http');
24+
const net = require('net');
25+
const PhoenixFS = require('@phcode/fs/dist/phoenix-fs');
26+
27+
function randomNonce(byteLength) {
28+
const randomBuffer = new Uint8Array(byteLength);
29+
crypto.getRandomValues(randomBuffer);
30+
31+
// Define the character set for the random string
32+
const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
33+
34+
// Convert the ArrayBuffer to a case-sensitive random string with numbers
35+
let randomId = '';
36+
Array.from(randomBuffer).forEach(byte => {
37+
randomId += charset[byte % charset.length];
38+
});
39+
40+
return randomId;
41+
}
42+
43+
const COMMAND_RESPONSE_PREFIX = 'phnodeResp:';
44+
// Generate a random 64-bit url. This should take 100 million+ of years to crack with current http connection speed.
45+
const PHOENIX_FS_URL = `/PhoenixFS${randomNonce(8)}`;
46+
const PHOENIX_NODE_URL = `/PhoenixNode${randomNonce(8)}`;
47+
48+
const savedConsoleLog = console.log;
49+
50+
const rl = readline.createInterface({
51+
input: process.stdin,
52+
output: process.stdout
53+
});
54+
55+
let serverPortResolve;
56+
const serverPortPromise = new Promise((resolve) => { serverPortResolve = resolve; });
57+
58+
let orphanExitTimer = setTimeout(()=>{
59+
process.exit(1);
60+
}, 60000);
61+
62+
function _sendResponse(responseMessage, commandID) {
63+
savedConsoleLog(COMMAND_RESPONSE_PREFIX + JSON.stringify({
64+
message: responseMessage,
65+
commandID
66+
}) + "\n");
67+
}
68+
69+
function processCommand(line) {
70+
try{
71+
let jsonCmd = JSON.parse(line);
72+
switch (jsonCmd.commandCode) {
73+
case "terminate": process.exit(0); return;
74+
case "heartBeat":
75+
clearTimeout(orphanExitTimer);
76+
orphanExitTimer = setTimeout(()=>{
77+
process.exit(1);
78+
}, 60000);
79+
return;
80+
case "ping": _sendResponse("pong", jsonCmd.commandID); return;
81+
case "setDebugMode":
82+
if(jsonCmd.commandData) {
83+
console.log = savedConsoleLog;
84+
} else {
85+
console.log = function () {}; // swallow logs
86+
}
87+
_sendResponse("done", jsonCmd.commandID); return;
88+
case "setPhoenixFSDebugMode":
89+
PhoenixFS.setDebugMode(jsonCmd.commandData);
90+
_sendResponse("done", jsonCmd.commandID); return;
91+
case "getEndpoints":
92+
serverPortPromise.then(port =>{
93+
_sendResponse({
94+
port,
95+
phoenixFSURL: `ws://localhost:${port}${PHOENIX_FS_URL}`,
96+
phoenixNodeURL: `ws://localhost:${port}${PHOENIX_NODE_URL}`
97+
}, jsonCmd.commandID);
98+
});
99+
return;
100+
default: console.error("unknown command: "+ line);
101+
}
102+
} catch (e) {
103+
console.error(e);
104+
}
105+
}
106+
107+
rl.on('line', (line) => {
108+
processCommand(line);
109+
});
110+
111+
function getFreePort() {
112+
return new Promise((resolve)=>{
113+
const server = net.createServer();
114+
115+
server.listen(0, () => {
116+
const port = server.address().port;
117+
server.close(() => {
118+
resolve(port);
119+
});
120+
});
121+
});
122+
}
123+
124+
// Create an HTTP server
125+
const server = http.createServer((req, res) => {
126+
res.writeHead(200, { 'Content-Type': 'text/plain' });
127+
res.end('WebSocket server running');
128+
});
129+
130+
getFreePort().then((port) => {
131+
console.log('Server Opened on port: ', port);
132+
133+
PhoenixFS.CreatePhoenixFsServer(server, PHOENIX_FS_URL);
134+
// Start the HTTP server on port 3000
135+
server.listen(port, () => {
136+
serverPortResolve(port);
137+
console.log(`Server running on http://localhost:${port}`);
138+
console.log(`Phoenix node tauri FS url is ws://localhost:${port}${PHOENIX_FS_URL}`);
139+
});
140+
141+
});

src-node/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-node/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
},
2020
"IMPORTANT!!": "Adding things here will bloat up the package size",
2121
"dependencies": {
22-
"@phcode/fs": "^2.0.5",
22+
"@phcode/fs": "^2.0.6",
2323
"npm": "10.1.0"
2424
}
2525
}

src/document/DocumentCommandHandlers.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1790,6 +1790,7 @@ define(function (require, exports, module) {
17901790

17911791
// Defer for a more successful reload - issue #11539
17921792
window.setTimeout(function () {
1793+
window.PhNodeEngine && window.PhNodeEngine.terminateNode();
17931794
window.location.href = href;
17941795
}, 1000);
17951796
}).fail(function () {
@@ -1900,6 +1901,7 @@ define(function (require, exports, module) {
19001901
event.preventDefault();
19011902
_handleWindowGoingAway(null, closeSuccess=>{
19021903
console.log('close success: ', closeSuccess);
1904+
window.PhNodeEngine.terminateNode();
19031905
Phoenix.app.closeWindow();
19041906
}, closeFail=>{
19051907
console.log('close fail: ', closeFail);

src/extensions/default/DebugCommands/main.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ define(function (require, exports, module) {
7171
DEBUG_RELOAD_WITHOUT_USER_EXTS = "debug.reloadWithoutUserExts",
7272
DEBUG_SWITCH_LANGUAGE = "debug.switchLanguage",
7373
DEBUG_ENABLE_LOGGING = "debug.enableLogging",
74+
DEBUG_ENABLE_PHNODE_INSPECTOR = "debug.enablePhNodeInspector",
7475
DEBUG_LIVE_PREVIEW_LOGGING = "debug.livePreviewLogging",
7576
DEBUG_OPEN_VFS = "debug.openVFS",
7677
DEBUG_OPEN_EXTENSION_FOLDER = "debug.openExtensionFolders",
@@ -688,13 +689,19 @@ define(function (require, exports, module) {
688689
CommandManager.get(DEBUG_LIVE_PREVIEW_LOGGING).setEnabled(isLogging);
689690
logger.loggingOptions.logLivePreview = window.isLoggingEnabled(LOG_LIVE_PREVIEW_KEY);
690691
CommandManager.get(DEBUG_LIVE_PREVIEW_LOGGING).setChecked(logger.loggingOptions.logLivePreview);
692+
CommandManager.get(DEBUG_ENABLE_PHNODE_INSPECTOR).setChecked(window.PhNodeEngine && window.PhNodeEngine.isInspectEnabled());
691693
}
692694

693695
function _handleLogging() {
694696
window.toggleLoggingKey(LOG_TO_CONSOLE_KEY);
695697
_updateLogToConsoleMenuItemChecked();
696698
}
697699

700+
function _handlePhNodeInspectEnable() {
701+
window.PhNodeEngine.setInspectEnabled(!window.PhNodeEngine.isInspectEnabled());
702+
_updateLogToConsoleMenuItemChecked();
703+
}
704+
698705
function _handleLivePreviewLogging() {
699706
window.toggleLoggingKey(LOG_LIVE_PREVIEW_KEY);
700707
_updateLogToConsoleMenuItemChecked();
@@ -749,6 +756,7 @@ define(function (require, exports, module) {
749756
CommandManager.register(switchLanguageStr, DEBUG_SWITCH_LANGUAGE, handleSwitchLanguage);
750757

751758
CommandManager.register(Strings.CMD_ENABLE_LOGGING, DEBUG_ENABLE_LOGGING, _handleLogging);
759+
CommandManager.register(Strings.CMD_ENABLE_PHNODE_INSPECTOR, DEBUG_ENABLE_PHNODE_INSPECTOR, _handlePhNodeInspectEnable);
752760
CommandManager.register(Strings.CMD_ENABLE_LIVE_PREVIEW_LOGS, DEBUG_LIVE_PREVIEW_LOGGING, _handleLivePreviewLogging);
753761
CommandManager.register(Strings.CMD_OPEN_VFS, DEBUG_OPEN_VFS, _openVFS);
754762
CommandManager.register(Strings.CMD_OPEN_EXTENSIONS_FOLDER, DEBUG_OPEN_EXTENSION_FOLDER, _openExtensionsFolder);
@@ -771,6 +779,9 @@ define(function (require, exports, module) {
771779
debugMenu.addMenuItem(DEBUG_SHOW_PERF_DATA);
772780
debugMenu.addMenuDivider();
773781
debugMenu.addMenuItem(DEBUG_ENABLE_LOGGING);
782+
debugMenu.addMenuItem(DEBUG_ENABLE_PHNODE_INSPECTOR, undefined, undefined, undefined, {
783+
hideWhenCommandDisabled: true
784+
});
774785
debugMenu.addMenuItem(DEBUG_LIVE_PREVIEW_LOGGING);
775786
debugMenu.addMenuDivider();
776787
debugMenu.addMenuItem(DEBUG_OPEN_VFS);
@@ -785,6 +796,8 @@ define(function (require, exports, module) {
785796
.setEnabled(extensionDevelopment.isProjectLoadedAsExtension());
786797
CommandManager.get(DEBUG_OPEN_EXTENSION_FOLDER)
787798
.setEnabled(Phoenix.browser.isTauri); // only show in tauri
799+
CommandManager.get(DEBUG_ENABLE_PHNODE_INSPECTOR)
800+
.setEnabled(Phoenix.browser.isTauri); // only show in tauri
788801
CommandManager.get(DEBUG_OPEN_VIRTUAL_SERVER)
789802
.setEnabled(!Phoenix.browser.isTauri); // don't show in tauri as there is no virtual server in tauri
790803

src/filesystem/impls/appshell/AppshellFileSystem.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ define(function (require, exports, module) {
469469
path = _normalise_path(path);
470470
if (typeof mode === "function") {
471471
callback = mode;
472-
mode = parseInt("0755", 8);
472+
mode = 0o755;
473473
}
474474
appshell.fs.mkdirs(path, mode, true, function (err) {
475475
if (err) {

src/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@
459459
<script src="phoenix/virtualfs.js" defer></script>
460460
<script src="phoenix/shell.js" type="module" defer></script>
461461
<script src="phoenix/virtual-server-loader.js" type="module" defer></script>
462+
<script src="node-loader.js" defer></script>
462463
<!-- end javascript module scripts-->
463464

464465
<!-- CSS/LESS -->

0 commit comments

Comments
 (0)