So, I tried to write a web server in Golang to fit in with zserge/lorca. Focusing on maximize/fullscreen on all platforms as well.
See the original post.
Tested with cURL's
% PORT=3000 ./webview-server
% curl -i -X PUT --data 'hello' http://127.0.0.1:3000/api/file\?filename\=test.txt
This, by default, works with lokijs, by using a custom adaptor.
import Loki from 'lokijs'
class LokiRestAdaptor {
loadDatabase (dbname: string, callback: (data: string | null | Error) => void) {
fetch(`/api/file?filename=${encodeURIComponent(dbname)}`)
.then((r) => r.text())
.then((r) => callback(r))
.catch((e) => callback(e))
}
saveDatabase (dbname: string, dbstring: string, callback: (e: Error | null) => void) {
fetch(`/api/file?filename=${encodeURIComponent(dbname)}`, {
method: 'PUT',
body: dbstring
})
.then(() => callback(null))
.catch((e) => callback(e))
}
deleteDatabase (dbname: string, callback: (data: Error | null) => void) {
fetch(`/api/file?filename=${encodeURIComponent(dbname)}`, {
method: 'DELETE'
})
.then(() => callback(null))
.catch((e) => callback(e))
}
}
// eslint-disable-next-line import/no-mutable-exports
export let loki: Loki
export async function initDatabase () {
return new Promise((resolve) => {
loki = new Loki('db.loki', {
adapter: new LokiRestAdaptor(),
autoload: true,
autoloadCallback: () => {
resolve()
},
autosave: true,
autosaveInterval: 4000
})
})
}
window.onbeforeunload = (e: Event) => {
if (loki) {
if (loki.autosaveDirty()) {
loki.saveDatabase()
e.preventDefault()
e.returnValue = false
}
}
}
And, in you Webpack dev server (e.g. webpack.config.js
)
// @ts-check
/* eslint-disable @typescript-eslint/no-var-requires */
const fs = require('fs')
const path = require('path')
const morgan = require('morgan')
const BINARY_DIR = 'release'
module.exports = {
devServer: {
/**
*
* @param {import('express').Express} app
* @param {import('http').Server} server
* @param {*} compiler
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
before (app, server, compiler) {
app.use('/api', morgan('tiny'))
app.get('/api/file', (req, res) => {
/** @type {*} */
const { filename } = req.query
const p = path.resolve(__dirname, BINARY_DIR, filename)
if (fs.existsSync(p)) {
fs.createReadStream(p).pipe(res)
return
}
res.sendStatus(404)
})
app.put('/api/file', (req, res) => {
/** @type {*} */
const { filename } = req.query
const p = path.resolve(__dirname, BINARY_DIR, filename)
req.pipe(fs.createWriteStream(p))
res.sendStatus(201)
})
app.delete('/api/file', (req, res) => {
/** @type {*} */
const { filename } = req.query
const p = path.resolve(__dirname, BINARY_DIR, filename)
fs.unlinkSync(p)
res.sendStatus(201)
})
}
}
}
Currently, this app doesn't bundle a web browser. Instead, it uses Chrome DevTools Protocol; therefore, either Chrome or Chromium must be installed.
See /deps.md.
I learnt this from pywebview. A major thing about this, is CSRF attack.
Please see /config/types.go. The easiest way is to create /config.yaml
alongside the built webview-server*
.
You can also build for your platform, or multiple platforms at once -- take a peek inside robo.yml
Note that executables in macOS can also run in windowed mode (no console), by renaming the extension to *.app
. No need to make a folder of *.app/
.
I cannot upload *.app
directly to GitHub Releases.
darwin
binaries can used for macOS, although not built natively on macOS.