331 lines
9.9 KiB
JavaScript
331 lines
9.9 KiB
JavaScript
(() => {
|
|
// node_modules/bloatless-react/index.ts
|
|
var State = class {
|
|
_value;
|
|
_bindings = /* @__PURE__ */ new Set();
|
|
// init
|
|
constructor(initialValue) {
|
|
this._value = initialValue;
|
|
}
|
|
// value
|
|
get value() {
|
|
return this._value;
|
|
}
|
|
set value(newValue) {
|
|
if (this._value == newValue) return;
|
|
this._value = newValue;
|
|
this.callSubscriptions();
|
|
}
|
|
// subscriptions
|
|
callSubscriptions() {
|
|
this._bindings.forEach((fn) => fn(this._value));
|
|
}
|
|
subscribe(fn) {
|
|
this._bindings.add(fn);
|
|
fn(this._value);
|
|
}
|
|
subscribeSilent(fn) {
|
|
this._bindings.add(fn);
|
|
}
|
|
// stringify
|
|
toString() {
|
|
return JSON.stringify(this._value);
|
|
}
|
|
};
|
|
function persistState(localStorageKey, state) {
|
|
state.subscribe(() => {
|
|
const stringifiedValue = state.toString();
|
|
localStorage.setItem(localStorageKey, stringifiedValue);
|
|
});
|
|
}
|
|
function restoreState(localStorageKey, initialStateValue) {
|
|
const storedString = localStorage.getItem(localStorageKey) ?? JSON.stringify(initialStateValue);
|
|
const convertedValue = JSON.parse(storedString);
|
|
const state = new State(convertedValue);
|
|
persistState(localStorageKey, state);
|
|
return state;
|
|
}
|
|
function createElement(tagName, attributes = {}, ...children) {
|
|
const element = document.createElement(tagName);
|
|
if (attributes != null)
|
|
Object.entries(attributes).forEach((entry) => {
|
|
const [attributename, value] = entry;
|
|
const [directiveKey, directiveValue] = attributename.split(":");
|
|
switch (directiveKey) {
|
|
case "on": {
|
|
switch (directiveValue) {
|
|
case "enter": {
|
|
element.addEventListener("keydown", (e) => {
|
|
if (e.key != "Enter") return;
|
|
value();
|
|
});
|
|
break;
|
|
}
|
|
default: {
|
|
element.addEventListener(directiveValue, value);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case "subscribe": {
|
|
const state = value;
|
|
state.subscribe(
|
|
(newValue) => element[directiveValue] = newValue
|
|
);
|
|
break;
|
|
}
|
|
case "bind": {
|
|
const state = value;
|
|
state.subscribe(
|
|
(newValue) => element[directiveValue] = newValue
|
|
);
|
|
element.addEventListener(
|
|
"input",
|
|
() => state.value = element[directiveValue]
|
|
);
|
|
break;
|
|
}
|
|
case "toggle": {
|
|
if (value.subscribe) {
|
|
const state = value;
|
|
state.subscribe(
|
|
(newValue) => element.toggleAttribute(directiveValue, newValue)
|
|
);
|
|
} else {
|
|
element.toggleAttribute(directiveValue, value);
|
|
}
|
|
break;
|
|
}
|
|
case "set": {
|
|
const state = value;
|
|
state.subscribe(
|
|
(newValue) => element.setAttribute(directiveValue, newValue)
|
|
);
|
|
break;
|
|
}
|
|
case "children": {
|
|
switch (directiveValue) {
|
|
case "set": {
|
|
const state = value;
|
|
state.subscribe((newValue) => {
|
|
element.innerHTML = "";
|
|
element.append(...[newValue].flat());
|
|
});
|
|
break;
|
|
}
|
|
case "append":
|
|
case "appendandscroll":
|
|
case "prepend": {
|
|
element.style.scrollBehavior = "smooth";
|
|
try {
|
|
const [listState, toElement] = value;
|
|
listState.handleAddition((newItem) => {
|
|
const child = toElement(newItem);
|
|
listState.handleRemoval(
|
|
newItem,
|
|
() => child.remove()
|
|
);
|
|
if (directiveValue == "append") {
|
|
element.append(child);
|
|
} else if (directiveValue == "prepend") {
|
|
element.prepend(child);
|
|
}
|
|
});
|
|
} catch {
|
|
throw `error: cannot process subscribe:children directive because StateItemConverter is not defined. Usage: "subscribe:children={[list, converter]}"; you can find a more detailed example in the documentation`;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
default:
|
|
element.setAttribute(attributename, value);
|
|
}
|
|
});
|
|
children.filter((x) => x).forEach((child) => element.append(child));
|
|
return element;
|
|
}
|
|
|
|
// node_modules/udn-frontend/index.ts
|
|
var UDNFrontend = class {
|
|
ws;
|
|
// HANDLERS
|
|
connectionHandler = () => {
|
|
};
|
|
disconnectionHandler = () => {
|
|
};
|
|
messageHandler = (data) => {
|
|
};
|
|
mailboxHandler = (mailboxId) => {
|
|
};
|
|
mailboxConnectionHandler = (mailboxId) => {
|
|
};
|
|
mailboxDeleteHandler = (mailboxId) => {
|
|
};
|
|
// INIT
|
|
set onconnect(handler) {
|
|
this.connectionHandler = handler;
|
|
}
|
|
set ondisconnect(handler) {
|
|
this.disconnectionHandler = handler;
|
|
}
|
|
set onmessage(handler) {
|
|
this.messageHandler = handler;
|
|
}
|
|
set onmailboxcreate(handler) {
|
|
this.mailboxHandler = handler;
|
|
}
|
|
set onmailboxconnect(handler) {
|
|
this.mailboxConnectionHandler = handler;
|
|
}
|
|
set onmailboxdelete(handler) {
|
|
this.mailboxDeleteHandler = handler;
|
|
}
|
|
// UTILITY METHODS
|
|
send(messageObject) {
|
|
if (this.ws == void 0) return false;
|
|
const messageString = JSON.stringify(messageObject);
|
|
this.ws.send(messageString);
|
|
return true;
|
|
}
|
|
// PUBLIC METHODS
|
|
// connection
|
|
connect(address) {
|
|
try {
|
|
this.disconnect();
|
|
this.ws = new WebSocket(address);
|
|
this.ws.addEventListener("open", this.connectionHandler);
|
|
this.ws.addEventListener("close", this.disconnectionHandler);
|
|
this.ws.addEventListener("message", (message) => {
|
|
const dataString = message.data.toString();
|
|
const data = JSON.parse(dataString);
|
|
if (data.assignedMailboxId) {
|
|
return this.mailboxHandler(data.assignedMailboxId);
|
|
} else if (data.connectedMailboxId) {
|
|
return this.mailboxConnectionHandler(data.connectedMailboxId);
|
|
} else if (data.deletedMailbox) {
|
|
return this.mailboxDeleteHandler(data.deletedMailbox);
|
|
} else {
|
|
this.messageHandler(data);
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error(error);
|
|
}
|
|
}
|
|
disconnect() {
|
|
this.ws?.close();
|
|
}
|
|
// message
|
|
sendMessage(channel, body) {
|
|
const messageObject = {
|
|
messageChannel: channel,
|
|
messageBody: body
|
|
};
|
|
return this.send(messageObject);
|
|
}
|
|
// subscription
|
|
subscribe(channel) {
|
|
const messageObject = {
|
|
subscribeChannel: channel
|
|
};
|
|
return this.send(messageObject);
|
|
}
|
|
unsubscribe(channel) {
|
|
const messageObject = {
|
|
unsubscribeChannel: channel
|
|
};
|
|
return this.send(messageObject);
|
|
}
|
|
// mailbox
|
|
requestMailbox() {
|
|
const messageObject = {
|
|
requestingMailboxSetup: true
|
|
};
|
|
return this.send(messageObject);
|
|
}
|
|
connectMailbox(mailboxId) {
|
|
const messageObject = {
|
|
requestedMailbox: mailboxId
|
|
};
|
|
return this.send(messageObject);
|
|
}
|
|
deleteMailbox(mailboxId) {
|
|
const messageObject = {
|
|
deletingMailbox: mailboxId
|
|
};
|
|
return this.send(messageObject);
|
|
}
|
|
};
|
|
|
|
// src/utility.ts
|
|
function stringify(data) {
|
|
return JSON.stringify(data);
|
|
}
|
|
|
|
// src/Model/connectionModel.ts
|
|
var ConnectionModel = class {
|
|
// basic
|
|
udn;
|
|
// data
|
|
get isConnected() {
|
|
return this.udn.ws != void 0 && this.udn.ws.readyState == 1;
|
|
}
|
|
get address() {
|
|
return this.udn.ws?.url;
|
|
}
|
|
// connection
|
|
connect = (address) => {
|
|
this.udn.connect(address);
|
|
};
|
|
disconnect = () => {
|
|
this.udn.disconnect();
|
|
};
|
|
handleConnectionChange = () => {
|
|
console.log("connection status:", this.isConnected, this.address);
|
|
};
|
|
// messaging
|
|
sendChatMessage = (chatMessage) => {
|
|
const stringifiedBody = stringify(chatMessage);
|
|
return this.udn.sendMessage(chatMessage.channel, stringifiedBody);
|
|
};
|
|
// setup
|
|
constructor(configuration) {
|
|
this.udn = new UDNFrontend();
|
|
this.udn.onmessage = (data) => {
|
|
configuration.messageHandler(data);
|
|
};
|
|
this.udn.onconnect = () => {
|
|
this.handleConnectionChange();
|
|
configuration.connectionChangeHandler();
|
|
};
|
|
this.udn.ondisconnect = () => {
|
|
this.handleConnectionChange();
|
|
configuration.connectionChangeHandler();
|
|
};
|
|
}
|
|
};
|
|
|
|
// src/View/maintenance.tsx
|
|
var addressInput = restoreState("maintenance-address", "");
|
|
var connectedAddress = new State("");
|
|
var isConnected = new State(false);
|
|
var connectionModel = new ConnectionModel({
|
|
connectionChangeHandler() {
|
|
isConnected.value = connectionModel.isConnected;
|
|
connectedAddress.value = connectionModel.address ?? "---";
|
|
},
|
|
messageHandler(data) {
|
|
console.log(data);
|
|
}
|
|
});
|
|
function connect() {
|
|
connectionModel.connect(addressInput.value);
|
|
}
|
|
function disconnect() {
|
|
connectionModel.disconnect();
|
|
}
|
|
document.querySelector("main").append(
|
|
/* @__PURE__ */ createElement("div", { class: "flex-column" }, /* @__PURE__ */ createElement("input", { "bind:value": addressInput }), /* @__PURE__ */ createElement("button", { "on:click": connect, "toggle:disabled": isConnected }, "Connect"), /* @__PURE__ */ createElement("button", { "on:click": disconnect }, "Disconnect"), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("span", { "subscribe:innerText": connectedAddress }))
|
|
);
|
|
})();
|