add PPPPP tech stack

This commit is contained in:
Andre Staltz 2024-01-05 16:27:54 +02:00
parent 1679fad72f
commit f3911e5f6b
No known key found for this signature in database
GPG Key ID: 9EDE23EA7E8A4890
7 changed files with 1529 additions and 61 deletions

71
main.js
View File

@ -1,13 +1,61 @@
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow, ipcMain } = require('electron')
const Path = require('node:path') const Path = require('node:path')
const URL = require('node:url') const URL = require('node:url')
const p = require('node:util').promisify
const Keypair = require('ppppp-keypair')
process.env.ZOOBOARD_DATA ??= Path.join(app.getPath('appData'), 'zooboard')
app.setPath('userData', process.env.ZOOBOARD_DATA)
const path = Path.resolve(app.getPath('userData'), 'ppppp')
const keypairPath = Path.join(path, 'keypair.json')
const keypair = Keypair.loadOrCreateSync(keypairPath)
const peer = require('secret-stack/bare')()
.use(require('secret-stack/plugins/net'))
.use(require('secret-handshake-ext/secret-stack'))
.use(require('ssb-conn'))
.use(require('ppppp-db'))
.use(require('ppppp-set'))
.use(require('ppppp-dict'))
.use(require('ppppp-goals'))
.use(require('ppppp-sync'))
.use(require('ppppp-gc'))
.use(require('ppppp-conductor'))
.use(require('ppppp-hub-client'))
.use(require('ppppp-promise'))
.use(require('ppppp-invite'))
.call(null, {
shse: {
caps: require('ppppp-caps'),
},
global: {
keypair,
path,
timers: {
inactivity: 10 * 60e3,
},
connections: {
incoming: {
tunnel: [{ transform: 'shse', scope: 'public' }],
},
outgoing: {
net: [{ transform: 'shse' }],
tunnel: [{ transform: 'shse' }],
},
},
},
conn: {
autostart: false,
},
})
// WARNING monkey patch! -------------------------------------- // WARNING monkey patch! --------------------------------------
// const na = require('sodium-native') const na = require('sodium-native')
// na.sodium_malloc = function sodium_malloc_monkey_patched(n) { na.sodium_malloc = function sodium_malloc_monkey_patched(n) {
// return Buffer.alloc(n) return Buffer.alloc(n)
// } }
// na.sodium_free = function sodium_free_monkey_patched() {} na.sodium_free = function sodium_free_monkey_patched() {}
// Electron > 20.3.8 breaks a napi method that `sodium_malloc` // Electron > 20.3.8 breaks a napi method that `sodium_malloc`
// depends on to create external buffers. (see v8 memory cage) // depends on to create external buffers. (see v8 memory cage)
// //
@ -19,6 +67,7 @@ function createWindow() {
const mainWindow = new BrowserWindow({ const mainWindow = new BrowserWindow({
width: 1200, width: 1200,
height: 800, height: 800,
title: 'Zooboard',
webPreferences: { webPreferences: {
preload: Path.join(__dirname, 'preload.js'), preload: Path.join(__dirname, 'preload.js'),
}, },
@ -32,12 +81,20 @@ function createWindow() {
slashes: true, slashes: true,
}) })
mainWindow.loadURL(startUrl) mainWindow.loadURL(startUrl)
// mainWindow.loadFile('index.html')
// mainWindow.webContents.openDevTools() // mainWindow.webContents.openDevTools()
} }
async function loadAccount() {
await peer.db.loaded()
const id = await p(peer.db.account.findOrCreate)({ subdomain: 'account' })
await p(peer.set.load)(id)
await p(peer.dict.load)(id)
return id
}
app.whenReady().then(() => { app.whenReady().then(() => {
ipcMain.handle('loadAccount', loadAccount)
createWindow() createWindow()
app.on('activate', function () { app.on('activate', function () {

1420
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -17,9 +17,24 @@
"@testing-library/jest-dom": "^5.17.0", "@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"ppppp-caps": "file:../caps",
"ppppp-keypair": "file:../keypair",
"ppppp-db": "file:../db",
"ppppp-dict": "file:../dict",
"ppppp-set": "file:../set",
"ppppp-goals": "file:../goals",
"ppppp-sync": "file:../sync",
"ppppp-gc": "file:../gc",
"ppppp-conductor": "file:../conductor",
"ppppp-hub-client": "file:../hub-client",
"ppppp-promise": "file:../promise",
"ppppp-invite": "file:../invite",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"secret-handshake-ext": "0.0.11",
"secret-stack": "8.0.0",
"ssb-conn": "6.0.4",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
"devDependencies": { "devDependencies": {

5
preload.js Normal file
View File

@ -0,0 +1,5 @@
const { contextBridge, ipcRenderer } = require('electron/renderer')
contextBridge.exposeInMainWorld('electronAPI', {
loadAccount: () => ipcRenderer.invoke('loadAccount')
})

View File

@ -2,42 +2,10 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" /> <title>Zooboard</title>
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div> <div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body> </body>
</html> </html>

View File

@ -1,19 +1,3 @@
.App {
text-align: center;
display: flex;
flex-direction: row;
}
.Sidebar {
width: 20vw;
background-color: #cbcfda;
}
.Main {
width: 80vw;
height: 100vh;
}
.excalidraw .dropdown-menu .dropdown-menu-item[data-testid="json-export-button"], .excalidraw .dropdown-menu .dropdown-menu-item[data-testid="json-export-button"],
.excalidraw .dropdown-menu .dropdown-menu-group, .excalidraw .dropdown-menu .dropdown-menu-group,
.excalidraw .dropdown-menu div:not([class]), .excalidraw .dropdown-menu div:not([class]),

View File

@ -1,13 +1,32 @@
import './App.css' import { useEffect, useState } from 'react'
import { Excalidraw } from '@excalidraw/excalidraw' import { Excalidraw } from '@excalidraw/excalidraw'
import './App.css'
function MyAccount() {
const [account, setAccountID] = useState(null)
useEffect(() => {
window.electronAPI.loadAccount().then((accountID) => {
setAccountID(accountID)
})
})
return (
<>
<span className="text-sm">My name is</span>
<span className="text-xs text-gray-500 font-mono overflow-x-hidden overflow-ellipsis">
{' ' + account}
</span>
</>
)
}
function App() { function App() {
return ( return (
<div className="App"> <div className="flex flex-row items-stretch h-screen">
<div className="Sidebar"> <div className="w-1/5 flex flex-col bg-gray-200 p-2">
<h1 className="text-3xl font-bold underline">Hello world!</h1> <MyAccount />
</div> </div>
<div className="Main"> <div className="w-4/5">
<Excalidraw <Excalidraw
UIOptions={{ UIOptions={{
canvasActions: { canvasActions: {