Live video on the AT Protocol
at eli/database-resync 128 lines 3.8 kB view raw
1import { app, dialog, ipcMain } from "electron"; 2import { parseArgs } from "node:util"; 3import "source-map-support/register"; 4import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"; 5import getEnv from "./env"; 6import makeNode from "./node"; 7import runTests, { allTestNames } from "./tests/test-runner"; 8import initUpdater from "./updater"; 9import { makeWindow } from "./window"; 10 11// Handle creating/removing shortcuts on Windows when installing/uninstalling. 12if (require("electron-squirrel-startup")) { 13 app.quit(); 14} else { 15 const { values: args, positionals } = parseArgs({ 16 options: { 17 path: { 18 type: "string", 19 default: "", 20 }, 21 "self-test": { 22 type: "boolean", 23 }, 24 "self-test-duration": { 25 type: "string", 26 default: "300000", 27 }, 28 "tests-to-run": { 29 type: "string", 30 default: allTestNames.join(","), 31 }, 32 }, 33 }); 34 const env = getEnv(); 35 console.log( 36 "starting with: ", 37 JSON.stringify({ args, positionals, env }, null, 2), 38 ); 39 40 app.on("ready", async () => { 41 let privateKey: `0x${string}`; 42 if (process.env.AQD_ADMIN_ACCOUNT_KEY) { 43 privateKey = process.env.AQD_ADMIN_ACCOUNT_KEY as `0x${string}`; 44 } else { 45 privateKey = generatePrivateKey(); 46 } 47 ipcMain.handle("getPrivateKey", () => privateKey); 48 const account = privateKeyToAccount(privateKey); 49 const env = { 50 SP_ADMIN_ACCOUNT: account.address.toLowerCase(), 51 SP_ALLOWED_STREAMS: account.address.toLowerCase(), 52 }; 53 if (args["self-test"]) { 54 const success = await runTests( 55 args["tests-to-run"].split(","), 56 args["self-test-duration"], 57 privateKey, 58 ); 59 if (!success) { 60 app.exit(1); 61 } else { 62 app.exit(0); 63 } 64 } else { 65 try { 66 await start(env); 67 } catch (e) { 68 console.error(e); 69 const dialogOpts: Electron.MessageBoxOptions = { 70 type: "info", 71 buttons: ["Quit Streamplace"], 72 title: "Error on Bootup", 73 message: 74 "Please report to the Streamplace developers at git.stream.place!", 75 detail: e.message + "\n" + e.stack, 76 }; 77 78 await dialog.showMessageBox(dialogOpts); 79 app.quit(); 80 } 81 } 82 }); 83 84 const start = async (env: { [k: string]: string }): Promise<void> => { 85 const { skipNode, nodeFrontend, noUpdate } = getEnv(); 86 if (!noUpdate) { 87 initUpdater(); 88 } 89 let loadAddr; 90 if (!skipNode) { 91 const { addr } = await makeNode({ env, autoQuit: true }); 92 loadAddr = addr; 93 } 94 const mainWindow = await makeWindow(); 95 96 let startPath; 97 if (nodeFrontend) { 98 startPath = `${loadAddr}${args.path}`; 99 } else { 100 startPath = `http://127.0.0.1:38081${args.path}`; 101 } 102 console.log(`opening ${startPath}`); 103 mainWindow.loadURL(startPath); 104 }; 105 106 // This method will be called when Electron has finished 107 // initialization and is ready to create browser windows. 108 // Some APIs can only be used after this event occurs. 109 110 // Quit when all windows are closed, except on macOS. There, it's common 111 // for applications and their menu bar to stay active until the user quits 112 // explicitly with Cmd + Q. 113 // app.on("window-all-closed", () => { 114 // if (process.platform !== "darwin") { 115 // app.quit(); 116 // } 117 // }); 118 119 app.on("activate", () => { 120 // On OS X it's common to re-create a window in the app when the 121 // dock icon is clicked and there are no other windows open. 122 // if (BrowserWindow.getAllWindows().length === 0) { 123 // } 124 }); 125 126 // In this file you can include the rest of your app's specific main process 127 // code. You can also put them in separate files and import them here. 128}