change webpack config and fine tune to use the frontend as a library

This commit is contained in:
Iris Lightshard 2024-12-07 18:04:04 -07:00
parent 508722feb5
commit 2c39f7fd3c
Signed by: Iris Lightshard
GPG key ID: 688407174966CAF3
9 changed files with 64 additions and 95 deletions

View file

@ -22,13 +22,24 @@ adapters receive commands via a quartzgun web API and send data back on their sh
requirements are
- go 1.22
- any recent nodejs that can do `typescript` and `webpack` 5
- go 1.22 (for the backend)
- any recent nodejs that can do `typescript` and `webpack` 5 (for the frontend)
from the project root:
1. `./build.sh front`
1. `./build.sh front` (if you will use the web components)
2. `./build.sh server`
3. `./underbbs`
3. `./underbbs` or `./underbbs-cli ADAPTER ACTION ARGS...`
visit `http://localhost:9090/app`
## integrating
### with the API and web components
1. fill `Settings._instance` with adapter settings; these will mostly be authentication data (`SettingsElement` illustrates this)
2. instantiate whatever components you want on your page with their `data-gateway` and `data-target` appropriately set; further docs to come on these
3. call `DatagramSocket.connect(GATEWAY)` where `GATEWAY` is the domain of the `underbbs` API. `SettingsElement`'s connect button does this for you.
### with the CLI
1. Call the CLI directly from the serverside or locally
2. Process any output to your preference

View file

@ -21,6 +21,7 @@ case "$1" in
server)
go mod tidy
go build
cp underbbs underbbs-cli
;;
*)
echo "usage: ${0} <front|server>"

View file

@ -1,29 +0,0 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<title>underBBS test</title>
<meta name="viewport" content="width=device-width" />
<link rel="shortcut icon" href="./favicon.png"/>
<link href="./style.css" rel="stylesheet" />
</head>
<body>
<noscript><div id="noscript_container">
JS app lol
</div>
</noscript>
<div id="err_wrapper" style='display:none'><button id="err_close" onclick="closeErr()">x</button><div id="err_div"></div></div>
<main>
<div class='uicolumn'>
<details open><summary>settings</summary><div id="settings_parent"></div></details>
<details open><summary>timeline-select</summary><div id="timeline_filter_parent"></div></details>
<details open><summary>timeline</summary><div id="timeline_parent"></div></details>
</div>
<div class='uicolumn'>
<details open><summary>profile</summary><div id="profile_parent"></div></details>
<details open><summary>honks</summary><div id="honks_parent"></div></details>
</div>
</main>
</body>
<script src="./main.js" type="application/javascript"></script>
</html>

View file

@ -1,52 +0,0 @@
import util from "./util"
import {AdapterState, AdapterData} from "./adapter";
import {Message, Attachment, Author} from "./message"
import {Settings} from "./settings"
import { MessageElement } from "./message-element"
import { SettingsElement } from "./settings-element"
import { ProfileElement } from "./profile-element"
import { AuthorMessagesElement } from "./author-messages-element"
import { TimelineElement } from "./timeline-element"
import { TimelineFilterElement } from "./timeline-filter-element"
import {DatagramSocket} from "./websocket"
function main() {
const saveData = localStorage.getItem("underbbs_settings");
Settings._instance = saveData ? <Settings>JSON.parse(saveData) : new Settings();
customElements.define("underbbs-message", MessageElement);
customElements.define("underbbs-settings", SettingsElement);
customElements.define("underbbs-profile", ProfileElement);
customElements.define("underbbs-author-messages", AuthorMessagesElement);
customElements.define("underbbs-timeline", TimelineElement);
customElements.define("underbbs-timeline-filter", TimelineFilterElement);
util._("closeErr", util.closeErr);
let settingsParent = util.$("settings_parent");
if (settingsParent) {
settingsParent.innerHTML = `<underbbs-settings data-adapters='${Settings._instance.adapters.map(a=>a.nickname).join(",")}' data-gateway=""></underbbs-settings>`
}
let profileParent = util.$("profile_parent");
if (profileParent) {
profileParent.innerHTML = "<underbbs-profile data-adapter='honk' data-target='https://cafe.nilfm.cc/u/nilix' data-gateway=''></underbbs-profile>"
}
let honksParent = util.$("honks_parent");
if (honksParent) {
honksParent.innerHTML = "<underbbs-author-messages data-adapter='honk' data-target='https://cafe.nilfm.cc/u/nilix' data-gateway=''></underbbs-author-messages>";
}
let timelineParent = util.$("timeline_parent");
if (timelineParent) {
timelineParent.innerHTML = "<underbbs-timeline id='honkstream' data-adapter='honk' data-target='home' data-gateway=''></underbbs-timeline>";
}
let timelineSelectParent = util.$("timeline_filter_parent");
if (timelineSelectParent) {
timelineSelectParent.innerHTML = "<underbbs-timeline-filter data-target='honkstream' data-filters='home::home/atme::atme'></underbbs-timeline-filter>";
}
}
main();

View file

@ -4,15 +4,17 @@ import {Settings} from "./settings"
export class SettingsElement extends HTMLElement {
static observedAttributes = [ "data-adapters" ]
static observedAttributes = [ "data-adapters", "data-gateway" ]
private _adapters: string[] = [];
private _gateway: string = "";
constructor() {
super();
}
connectedCallback() {
this._gateway = this.getAttribute("data-gateway") ?? "";
}
attributeChangedCallback(attr: string, prev: string, next: string) {
@ -49,7 +51,7 @@ export class SettingsElement extends HTMLElement {
}
let connect = util.$("settings_connect_btn");
if (connect) {
connect.addEventListener("click", DatagramSocket.connect, false);
connect.addEventListener("click", ()=>{DatagramSocket.connect(this._gateway)}, false);
}
}
}

View file

@ -2,11 +2,17 @@ import util from "./util"
import {AdapterState, AdapterData} from "./adapter";
import {Message, Attachment, Author} from "./message"
import {Settings} from "./settings"
import {SettingsElement} from "./settings-element"
import {AuthorMessagesElement} from "./author-messages-element"
import {ProfileElement} from "./profile-element"
import {MessageElement} from "./message-element"
import {TimelineElement} from "./timeline-element"
import {TimelineFilterElement} from "./timeline-filter-element"
export class DatagramSocket {
public static skey: string | null = null;
public static conn: WebSocket | null;
private static _gateway: string = ""
private static onOpen(e: Event) {
@ -14,12 +20,16 @@ export class DatagramSocket {
console.log(JSON.stringify(e));
}
private static gatewayWithScheme(): string {
return location.protocol + "//" + DatagramSocket._gateway
}
private static onMsg(e: MessageEvent) {
const data = JSON.parse(e.data);
console.log(data);
if (data.key) {
DatagramSocket.skey = data.key;
util.authorizedFetch("POST", "/api/adapters", JSON.stringify(Settings._instance.adapters))
util.authorizedFetch("POST", DatagramSocket.gatewayWithScheme() + "/api/adapters", JSON.stringify(Settings._instance.adapters))
.then(r=> {
if (r.ok) {
// iterate through any components which might want to fetch data
@ -89,9 +99,17 @@ export class DatagramSocket {
}
}
static connect(): void {
static connect(gateway: string): void {
DatagramSocket._gateway = gateway;
const wsProto = location.protocol == "https:" ? "wss" : "ws";
const _conn = new WebSocket(`${wsProto}://${location.host}/subscribe`, "underbbs");
let wsUrl = ""
if (!gateway) {
wsUrl = `${wsProto}://${location.host}/subscribe`;
} else {
wsUrl = wsProto + "://" + gateway + "/subscribe"
}
const _conn = new WebSocket(wsUrl, "underbbs");
_conn.addEventListener("open", DatagramSocket.onOpen);
_conn.addEventListener("message", DatagramSocket.onMsg);
@ -104,3 +122,19 @@ export class DatagramSocket {
}
}
function init() {
const saveData = localStorage.getItem("underbbs_settings");
Settings._instance = saveData ? JSON.parse(saveData) : new Settings();
customElements.define("underbbs-message", MessageElement);
customElements.define("underbbs-settings", SettingsElement);
customElements.define("underbbs-profile", ProfileElement);
customElements.define("underbbs-author-messages", AuthorMessagesElement);
customElements.define("underbbs-timeline", TimelineElement);
customElements.define("underbbs-timeline-filter", TimelineFilterElement);
console.log("underbbs initialized!")
}
init();

View file

@ -60,7 +60,8 @@ func (self *BBSServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
func (self *BBSServer) subscribeHandler(w http.ResponseWriter, r *http.Request) {
c, err := websocket.Accept(w, r, &websocket.AcceptOptions{
Subprotocols: []string{},
Subprotocols: []string{},
OriginPatterns: []string{"*"},
})
if err != nil {
self.logf("%v", err)

View file

@ -4,9 +4,10 @@ module.exports = {
mode: 'production',
context: path.resolve(__dirname, 'frontend', '.js'),
entry: {
main: './index.js',
underbbs: './websocket.js',
},
output: {
iife: false,
filename: '[name].js',
path: path.resolve(__dirname, 'frontend', 'dist'),
},