mirror of
https://github.com/mileswolfallen2/gelectron.git
synced 2026-09-08 12:43:16 +00:00
update
This commit is contained in:
+7
-3
@@ -5,6 +5,7 @@ crates/*/target/
|
||||
# Node.js
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
package-lock.json
|
||||
|
||||
# Build artifacts
|
||||
*.node
|
||||
@@ -14,6 +15,12 @@ npm-debug.log*
|
||||
*.d
|
||||
*.pdb
|
||||
|
||||
# Benchmark results
|
||||
benchmark/result-*.json
|
||||
|
||||
# Electron
|
||||
electron/
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
@@ -24,8 +31,5 @@ Thumbs.db
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Cargo
|
||||
Cargo.lock
|
||||
|
||||
# napi-rs
|
||||
napi-dist/
|
||||
|
||||
Generated
+5572
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,219 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Benchmark</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, system-ui, sans-serif;
|
||||
background: #0d1117;
|
||||
color: #e6edf3;
|
||||
padding: 32px;
|
||||
}
|
||||
h1 { font-size: 22px; font-weight: 600; margin-bottom: 4px; }
|
||||
.subtitle { color: #8b949e; font-size: 13px; margin-bottom: 28px; }
|
||||
.section { margin-bottom: 24px; }
|
||||
.section-title { font-size: 13px; font-weight: 600; color: #8b949e; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 10px; }
|
||||
.card {
|
||||
background: #161b22;
|
||||
border: 1px solid #30363d;
|
||||
border-radius: 8px;
|
||||
padding: 16px 20px;
|
||||
}
|
||||
.row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid #21262d;
|
||||
}
|
||||
.row:last-child { border-bottom: none; }
|
||||
.label { font-size: 14px; color: #c9d1d9; }
|
||||
.value { font-size: 14px; font-weight: 600; font-variant-numeric: tabular-nums; }
|
||||
.status { font-size: 14px; color: #8b949e; margin-bottom: 20px; }
|
||||
.status .dot {
|
||||
display: inline-block;
|
||||
width: 8px; height: 8px;
|
||||
border-radius: 50%;
|
||||
margin-right: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.dot.running { background: #d29922; animation: pulse 1s infinite; }
|
||||
.dot.done { background: #3fb950; }
|
||||
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.4} }
|
||||
#results { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="title">Benchmark</h1>
|
||||
<p class="subtitle" id="subtitle"></p>
|
||||
<div class="status"><span class="dot running" id="dot"></span><span id="status-text">Initializing…</span></div>
|
||||
<div id="results">
|
||||
<div class="section">
|
||||
<div class="section-title">Renderer Performance</div>
|
||||
<div class="card" id="perf-card"></div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="section-title">Memory (Main Process)</div>
|
||||
<div class="card" id="mem-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="target" style="position:absolute;left:-9999px"></div>
|
||||
<script>
|
||||
try {
|
||||
var isG = !!(process.versions && process.versions.gelectron);
|
||||
document.getElementById('title').textContent = (isG ? 'Gelectron' : 'Electron') + ' Benchmark';
|
||||
document.getElementById('subtitle').textContent = process.platform + ' ' + process.arch + ' | Node ' + process.versions.node;
|
||||
} catch(e) {}
|
||||
|
||||
function setStatus(t, done) {
|
||||
document.getElementById('status-text').textContent = t;
|
||||
document.getElementById('dot').className = done ? 'dot done' : 'dot running';
|
||||
}
|
||||
|
||||
function bench(name, fn, iter) {
|
||||
for (var i = 0; i < Math.min(iter, 50); i++) fn();
|
||||
var times = [];
|
||||
var bs = Math.max(1, Math.floor(iter / 10));
|
||||
for (var b = 0; b < 10; b++) {
|
||||
var t0 = performance.now();
|
||||
for (var j = 0; j < bs; j++) fn();
|
||||
times.push(performance.now() - t0);
|
||||
}
|
||||
var total = times.reduce(function(a,b){return a+b},0);
|
||||
var ops = bs * 10;
|
||||
return {
|
||||
timeMs: +(total / 10).toFixed(2),
|
||||
opsPerSec: +((ops / total) * 1000).toFixed(0)
|
||||
};
|
||||
}
|
||||
|
||||
function fmtOps(o) {
|
||||
if (o >= 1e6) return (o/1e6).toFixed(2) + 'M';
|
||||
if (o >= 1e3) return (o/1e3).toFixed(1) + 'K';
|
||||
return '' + o;
|
||||
}
|
||||
|
||||
function row(label, val) {
|
||||
return '<div class="row"><span class="label">' + label + '</span><span class="value">' + val + '</span></div>';
|
||||
}
|
||||
|
||||
(async function() {
|
||||
var t = document.getElementById('target');
|
||||
var tests = {};
|
||||
var s = performance.now();
|
||||
|
||||
setStatus('DOM create / append…');
|
||||
await new Promise(function(r){setTimeout(r,0)});
|
||||
tests['DOM create/append'] = bench('dc', function() {
|
||||
var el = document.createElement('div');
|
||||
el.textContent = 'Hello';
|
||||
t.appendChild(el);
|
||||
t.removeChild(el);
|
||||
}, 10000);
|
||||
|
||||
setStatus('DOM querySelector…');
|
||||
await new Promise(function(r){setTimeout(r,0)});
|
||||
t.innerHTML = '';
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
var el = document.createElement('div');
|
||||
el.dataset.idx = i;
|
||||
t.appendChild(el);
|
||||
}
|
||||
tests['DOM querySelector'] = bench('dq', function() {
|
||||
t.querySelector('[data-idx="500"]');
|
||||
}, 30000);
|
||||
|
||||
setStatus('Style recalc…');
|
||||
await new Promise(function(r){setTimeout(r,0)});
|
||||
var sty = document.createElement('style');
|
||||
sty.textContent = '.s{color:red;font-size:14px;padding:8px;margin:4px;border:1px solid #000}';
|
||||
document.head.appendChild(sty);
|
||||
t.innerHTML = '';
|
||||
for (var i = 0; i < 500; i++) {
|
||||
var el = document.createElement('div');
|
||||
el.className = 's';
|
||||
el.textContent = 'Item ' + i;
|
||||
t.appendChild(el);
|
||||
}
|
||||
tests['Style recalc'] = bench('sr', function() {
|
||||
var items = t.querySelectorAll('.s');
|
||||
for (var k = 0; k < items.length; k++) {
|
||||
items[k].classList.toggle('s');
|
||||
void items[k].offsetHeight;
|
||||
}
|
||||
}, 5000);
|
||||
|
||||
setStatus('Canvas 2D draw…');
|
||||
await new Promise(function(r){setTimeout(r,0)});
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = 800; canvas.height = 600;
|
||||
document.body.appendChild(canvas);
|
||||
var ctx = canvas.getContext('2d');
|
||||
tests['Canvas 2D draw'] = bench('cv', function() {
|
||||
ctx.fillStyle = '#4ecdc4';
|
||||
ctx.fillRect(0, 0, 100, 100);
|
||||
ctx.strokeStyle = '#ff6b6b';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.beginPath();
|
||||
ctx.arc(200, 200, 50, 0, Math.PI * 2);
|
||||
ctx.stroke();
|
||||
ctx.font = '16px sans-serif';
|
||||
ctx.fillText('Benchmark', 300, 300);
|
||||
}, 15000);
|
||||
|
||||
setStatus('JSON parse…');
|
||||
await new Promise(function(r){setTimeout(r,0)});
|
||||
var bigArr = [];
|
||||
for (var i = 0; i < 500; i++) bigArr.push({id:i,vals:[Math.random(),Math.random()]});
|
||||
var bigStr = JSON.stringify(bigArr);
|
||||
tests['JSON parse'] = bench('js', function() { JSON.parse(bigStr); }, 20000);
|
||||
|
||||
setStatus('Array sort (10k)…');
|
||||
await new Promise(function(r){setTimeout(r,0)});
|
||||
tests['Array sort (10k)'] = bench('as', function() {
|
||||
var a = [];
|
||||
for (var i = 0; i < 10000; i++) a.push(Math.random());
|
||||
a.sort(function(x,y){return x-y});
|
||||
}, 500);
|
||||
|
||||
setStatus('Fibonacci(25)…');
|
||||
await new Promise(function(r){setTimeout(r,0)});
|
||||
function fib(n) { return n <= 1 ? n : fib(n-1) + fib(n-2); }
|
||||
tests['Fibonacci(25)'] = bench('fb', function() { fib(25); }, 30);
|
||||
|
||||
setStatus('Collecting memory…', false);
|
||||
await new Promise(function(r){setTimeout(r,0)});
|
||||
var mem = {};
|
||||
try {
|
||||
var m = process.memoryUsage();
|
||||
mem = {
|
||||
RSS: (m.rss/1048576).toFixed(1) + ' MB',
|
||||
'Heap used': (m.heapUsed/1048576).toFixed(1) + ' MB',
|
||||
'Heap total': (m.heapTotal/1048576).toFixed(1) + ' MB',
|
||||
External: (m.external/1048576).toFixed(1) + ' MB'
|
||||
};
|
||||
} catch(e) { mem = {Note: 'memory not available'}; }
|
||||
|
||||
var elapsed = ((performance.now() - s) / 1000).toFixed(1);
|
||||
setStatus('Done in ' + elapsed + 's — close window to exit', true);
|
||||
|
||||
// Render
|
||||
var perf = document.getElementById('perf-card');
|
||||
var h = '';
|
||||
for (var name in tests) {
|
||||
h += row(name, fmtOps(tests[name].opsPerSec) + ' ops/s (' + tests[name].timeMs + ' ms)');
|
||||
}
|
||||
perf.innerHTML = h;
|
||||
|
||||
var mc = document.getElementById('mem-card');
|
||||
h = '';
|
||||
for (var k in mem) h += row(k, mem[k]);
|
||||
mc.innerHTML = h;
|
||||
|
||||
document.getElementById('results').style.display = 'block';
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,22 @@
|
||||
const { app, BrowserWindow } = require('electron');
|
||||
const path = require('path');
|
||||
|
||||
const isGelectron = !!(process.versions.gelectron || process.env.GELECTRON_NATIVE);
|
||||
|
||||
app.whenReady().then(() => {
|
||||
const win = new BrowserWindow({
|
||||
width: 680,
|
||||
height: 720,
|
||||
show: true,
|
||||
title: (isGelectron ? 'Gelectron' : 'Electron') + ' Benchmark',
|
||||
webPreferences: {
|
||||
contextIsolation: false,
|
||||
nodeIntegration: true,
|
||||
sandbox: false,
|
||||
},
|
||||
});
|
||||
|
||||
win.loadFile(path.join(__dirname, 'index.html'));
|
||||
});
|
||||
|
||||
app.on('window-all-closed', () => app.quit());
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "gelectron-benchmark",
|
||||
"version": "1.0.0",
|
||||
"description": "Simple web benchmark for comparing Electron vs Gelectron",
|
||||
"main": "main.js"
|
||||
}
|
||||
Executable
+79
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
BENCH_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
ELECTRON_BIN="$BENCH_DIR/node_modules/.bin/electron"
|
||||
GEELECTRON_BIN="$BENCH_DIR/../target/release/gelectron"
|
||||
|
||||
usage() {
|
||||
echo ""
|
||||
echo " Usage: ./benchmark/run.sh [options]"
|
||||
echo ""
|
||||
echo " Options:"
|
||||
echo " --electron Run with Electron only"
|
||||
echo " --gelectron Run with Gelectron only"
|
||||
echo " (no args) Run both back-to-back"
|
||||
echo ""
|
||||
}
|
||||
|
||||
run_electron() {
|
||||
if [ -x "$ELECTRON_BIN" ] || command -v electron &>/dev/null; then
|
||||
local bin="${ELECTRON_BIN:-electron}"
|
||||
echo ""
|
||||
echo " ▶ Opening Electron benchmark…"
|
||||
echo " Close the window when done."
|
||||
"$bin" "$BENCH_DIR" 2>/dev/null
|
||||
echo " ✓ Electron done"
|
||||
else
|
||||
echo ""
|
||||
echo " ✗ Electron not found. Install with: npm install electron"
|
||||
fi
|
||||
}
|
||||
|
||||
run_gelectron() {
|
||||
if [ -x "$GEELECTRON_BIN" ]; then
|
||||
echo ""
|
||||
echo " ▶ Opening Gelectron benchmark…"
|
||||
echo " Close the window when done."
|
||||
"$GEELECTRON_BIN" "$BENCH_DIR" 2>/dev/null
|
||||
echo " ✓ Gelectron done"
|
||||
elif command -v gelectron &>/dev/null; then
|
||||
echo ""
|
||||
echo " ▶ Opening Gelectron benchmark…"
|
||||
echo " Close the window when done."
|
||||
gelectron "$BENCH_DIR" 2>/dev/null
|
||||
echo " ✓ Gelectron done"
|
||||
else
|
||||
echo ""
|
||||
echo " ✗ Gelectron not found. Build with: cargo build --release"
|
||||
fi
|
||||
}
|
||||
|
||||
MODE="both"
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--electron) MODE="electron" ;;
|
||||
--gelectron) MODE="gelectron" ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) echo " Unknown option: $arg"; usage; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo " ── Gelectron Benchmark ──"
|
||||
|
||||
if [ "$MODE" = "both" ] || [ "$MODE" = "electron" ]; then
|
||||
run_electron
|
||||
fi
|
||||
|
||||
if [ "$MODE" = "both" ] || [ "$MODE" = "gelectron" ]; then
|
||||
run_gelectron
|
||||
fi
|
||||
|
||||
if [ "$MODE" = "both" ]; then
|
||||
echo ""
|
||||
echo " ── Done ──"
|
||||
echo " Both benchmarks ran. Results are shown in each window."
|
||||
echo " The second window auto-loads a comparison if result files exist."
|
||||
echo ""
|
||||
fi
|
||||
@@ -129,10 +129,14 @@ fn preload_script() -> String {
|
||||
(function() {
|
||||
if (window.__gelectron_loaded) return;
|
||||
window.__gelectron_loaded = true;
|
||||
window.__ipc_pending = [];
|
||||
window.gelectron = {
|
||||
send: function(channel, ...args) {
|
||||
window.__ipc_pending.push(JSON.stringify({channel: channel, args: args}));
|
||||
var payload = JSON.stringify({type:'ipc-send', channel: channel, args: args});
|
||||
if (window.ipc && window.ipc.postMessage) {
|
||||
window.ipc.postMessage(payload);
|
||||
} else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.ipc) {
|
||||
window.webkit.messageHandlers.ipc.postMessage(payload);
|
||||
}
|
||||
},
|
||||
receive: function(channel, callback) {
|
||||
window.addEventListener('message', function(e) {
|
||||
@@ -313,6 +317,7 @@ require('{}');
|
||||
});
|
||||
|
||||
let event_loop = EventLoopBuilder::new().build();
|
||||
let (ipc_tx, ipc_rx) = mpsc::channel::<ToNode>();
|
||||
let mut state = AppState::new(node_exited.clone());
|
||||
state.node_stdin = Some(child_stdin);
|
||||
let state = Rc::new(RefCell::new(state));
|
||||
@@ -325,7 +330,6 @@ require('{}');
|
||||
|
||||
// If the Node.js child process has exited, shut down
|
||||
if st.node_exited.load(Ordering::SeqCst) {
|
||||
log::info!("Node.js process exited, shutting down");
|
||||
st.windows.clear();
|
||||
st.window_wids.clear();
|
||||
*control_flow = ControlFlow::Exit;
|
||||
@@ -334,6 +338,10 @@ require('{}');
|
||||
|
||||
match event {
|
||||
Event::NewEvents(StartCause::Poll) => {
|
||||
// Drain IPC messages from webview → Node
|
||||
while let Ok(msg) = ipc_rx.try_recv() {
|
||||
st.send_to_node(&msg);
|
||||
}
|
||||
while let Ok(msg) = rx.try_recv() {
|
||||
match msg {
|
||||
ToRust::CreateWindow { id, options } => {
|
||||
@@ -354,20 +362,33 @@ require('{}');
|
||||
Ok(window) => {
|
||||
let url = options.url.unwrap_or_else(|| "about:blank".into());
|
||||
log::info!("Creating window {} - '{}'", id, url);
|
||||
match WebViewBuilder::new()
|
||||
.with_url(&url)
|
||||
.with_initialization_script(&preload_script())
|
||||
.with_devtools(true)
|
||||
.build(&window)
|
||||
{
|
||||
Ok(webview) => {
|
||||
let wid = window.id();
|
||||
st.windows.insert(id, WindowPair { window, webview });
|
||||
st.window_wids.insert(wid, id);
|
||||
log::info!("Window {} ready", id);
|
||||
let ipc_tx_clone = ipc_tx.clone();
|
||||
let wid_for_ipc = id;
|
||||
match WebViewBuilder::new()
|
||||
.with_url(&url)
|
||||
.with_initialization_script(&preload_script())
|
||||
.with_devtools(true)
|
||||
.with_ipc_handler(move |req| {
|
||||
let body = req.body().to_string();
|
||||
if let Ok(msg) = serde_json::from_str::<serde_json::Value>(&body) {
|
||||
let msg_type = msg.get("type").and_then(|v| v.as_str()).unwrap_or("");
|
||||
if msg_type == "ipc-send" {
|
||||
let channel = msg.get("channel").and_then(|v| v.as_str()).unwrap_or("");
|
||||
let args = msg.get("args").cloned().unwrap_or(serde_json::Value::Null);
|
||||
let _ = ipc_tx_clone.send(ToNode::IpcMessage { id: wid_for_ipc, channel: channel.to_string(), data: args });
|
||||
}
|
||||
}
|
||||
Err(e) => log::error!("WebView error: {}", e),
|
||||
})
|
||||
.build(&window)
|
||||
{
|
||||
Ok(webview) => {
|
||||
let wid = window.id();
|
||||
st.windows.insert(id, WindowPair { window, webview });
|
||||
st.window_wids.insert(wid, id);
|
||||
log::info!("Window {} ready", id);
|
||||
}
|
||||
Err(e) => log::error!("WebView error: {}", e),
|
||||
}
|
||||
}
|
||||
Err(e) => log::error!("Window error: {}", e),
|
||||
}
|
||||
@@ -385,15 +406,25 @@ require('{}');
|
||||
ToRust::LoadFile { id, path } => {
|
||||
let url = format!("file://{}", std::fs::canonicalize(&path).unwrap_or_default().display());
|
||||
log::info!("Loading file in window {}: {}", id, url);
|
||||
// Rebuild the WebView with the correct file URL.
|
||||
// evaluate_script navigation from about:blank to file:// is
|
||||
// unreliable on macOS WKWebView, so we recreate the WebView.
|
||||
if let Some(pair) = st.windows.get_mut(&id) {
|
||||
let window = &pair.window;
|
||||
let ipc_tx_clone = ipc_tx.clone();
|
||||
let wid_for_ipc = id;
|
||||
match WebViewBuilder::new()
|
||||
.with_url(&url)
|
||||
.with_initialization_script(&preload_script())
|
||||
.with_devtools(true)
|
||||
.with_ipc_handler(move |req| {
|
||||
let body = req.body().to_string();
|
||||
if let Ok(msg) = serde_json::from_str::<serde_json::Value>(&body) {
|
||||
let msg_type = msg.get("type").and_then(|v| v.as_str()).unwrap_or("");
|
||||
if msg_type == "ipc-send" {
|
||||
let channel = msg.get("channel").and_then(|v| v.as_str()).unwrap_or("");
|
||||
let args = msg.get("args").cloned().unwrap_or(serde_json::Value::Null);
|
||||
let _ = ipc_tx_clone.send(ToNode::IpcMessage { id: wid_for_ipc, channel: channel.to_string(), data: args });
|
||||
}
|
||||
}
|
||||
})
|
||||
.build(window)
|
||||
{
|
||||
Ok(webview) => {
|
||||
|
||||
Generated
+131
-2
@@ -7,16 +7,55 @@
|
||||
"": {
|
||||
"name": "gelectron",
|
||||
"version": "0.1.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"gelectron": "cli/gelectron.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@napi-rs/cli": "^3.0.0"
|
||||
"@napi-rs/cli": "^3.0.0",
|
||||
"electron": "^43.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"gelectron-darwin-arm64": "0.1.0",
|
||||
"gelectron-darwin-x64": "0.1.0",
|
||||
"gelectron-linux-arm64-gnu": "0.1.0",
|
||||
"gelectron-linux-x64-gnu": "0.1.0",
|
||||
"gelectron-win32-arm64-msvc": "0.1.0",
|
||||
"gelectron-win32-x64-msvc": "0.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-internal/extract-zip": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@electron-internal/extract-zip/-/extract-zip-1.0.4.tgz",
|
||||
"integrity": "sha512-Zr1Vs7E9tpCNhZHDAbFVXc2gEVCG9RqPDjrno5+bdgB6LRAuvgyMHJut4NCVyYwtAieapMzc3fiQ3CSTi75ARg==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/get": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron/get/-/get-5.0.0.tgz",
|
||||
"integrity": "sha512-pjoBpru1KdEtcExBnuHAP1cAc/5faoedw0hzJkL3o4/IJp7HNF1+fbrdxT3gMYRX2oJfvnA/WXeCTVQpYYxyJA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.1.1",
|
||||
"env-paths": "^3.0.0",
|
||||
"graceful-fs": "^4.2.11",
|
||||
"progress": "^2.0.3",
|
||||
"semver": "^7.6.3",
|
||||
"sumchecker": "^3.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"undici": "^7.24.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/core": {
|
||||
@@ -1654,6 +1693,16 @@
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "24.13.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz",
|
||||
"integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~7.18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
@@ -1740,6 +1789,25 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/electron": {
|
||||
"version": "43.2.0",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-43.2.0.tgz",
|
||||
"integrity": "sha512-80zvrgG7ZRXD+tD0IyLvrnN9n+veSxadMRsMaC9wKKP3iUbtC7rGM8+dVuCmOb0Rrwwv8ESW4awnUZh9Hbp1fA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-internal/extract-zip": "^1.0.1",
|
||||
"@electron/get": "^5.0.0",
|
||||
"@types/node": "^24.9.0"
|
||||
},
|
||||
"bin": {
|
||||
"electron": "cli.js",
|
||||
"install-electron": "install.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/emnapi": {
|
||||
"version": "1.11.3",
|
||||
"resolved": "https://registry.npmjs.org/emnapi/-/emnapi-1.11.3.tgz",
|
||||
@@ -1755,6 +1823,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/env-paths": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz",
|
||||
"integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/es-toolkit": {
|
||||
"version": "1.50.0",
|
||||
"resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.50.0.tgz",
|
||||
@@ -1794,6 +1875,13 @@
|
||||
"fast-string-width": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz",
|
||||
@@ -1872,6 +1960,16 @@
|
||||
"node": ">=12.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/progress": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
|
||||
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
@@ -1905,6 +2003,19 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/sumchecker": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
|
||||
"integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"debug": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
@@ -1923,6 +2034,24 @@
|
||||
"website"
|
||||
]
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "7.29.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-7.29.0.tgz",
|
||||
"integrity": "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=20.18.1"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "7.18.2",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
|
||||
"integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/universal-user-agent": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz",
|
||||
|
||||
+6
-5
@@ -51,7 +51,8 @@
|
||||
"author": "mileswa1q22",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@napi-rs/cli": "^3.0.0"
|
||||
"@napi-rs/cli": "^3.0.0",
|
||||
"electron": "^43.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
@@ -59,9 +60,9 @@
|
||||
"optionalDependencies": {
|
||||
"gelectron-darwin-arm64": "0.1.0",
|
||||
"gelectron-darwin-x64": "0.1.0",
|
||||
"gelectron-win32-x64-msvc": "0.1.0",
|
||||
"gelectron-win32-arm64-msvc": "0.1.0",
|
||||
"gelectron-linux-arm64-gnu": "0.1.0",
|
||||
"gelectron-linux-x64-gnu": "0.1.0",
|
||||
"gelectron-linux-arm64-gnu": "0.1.0"
|
||||
"gelectron-win32-arm64-msvc": "0.1.0",
|
||||
"gelectron-win32-x64-msvc": "0.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user