From aade48a7b8e64e172fcfee196eb93f19a1b61102 Mon Sep 17 00:00:00 2001 From: bobbydigitales Date: Sun, 13 Apr 2025 15:10:07 -0700 Subject: [PATCH] wip v2 --- deno/ddln_server.ts | 49 +- ranting.md | 6 +- src/IDUtils.ts | 13 + src/PeerManager.ts | 544 +++++++++++ src/log.ts | 28 + src/main.ts | 130 ++- src/main2.ts | 2114 ++++++++++++++++++++++++++++++++++++++++++ src/sw.ts | 4 +- src/webRTC.ts | 110 --- static/index.html | 8 +- static/main.css | 2 +- static/main.js | 98 +- static/main.js.map | 2 +- static/sw.js | 4 +- static/sw.js.map | 2 +- static/webRTC.js | 205 ++-- static/webRTC.js.map | 2 +- webRTC.js | 163 ++-- 18 files changed, 3185 insertions(+), 299 deletions(-) create mode 100644 src/IDUtils.ts create mode 100644 src/PeerManager.ts create mode 100644 src/log.ts create mode 100644 src/main2.ts delete mode 100644 src/webRTC.ts diff --git a/deno/ddln_server.ts b/deno/ddln_server.ts index c2b1038..85f199d 100644 --- a/deno/ddln_server.ts +++ b/deno/ddln_server.ts @@ -7,6 +7,8 @@ // import { serveDir } from "jsr:@std/http/file-server" +import { brotli } from "jsr:@deno-library/compress"; + const memoryCache = true; const filepathResponseCache: Map = new Map(); @@ -30,9 +32,15 @@ async function serveFile(filename: string) { const file = await Deno.readFile("../" + filename); - const newResponse = new Response(file); + + const compressed = await brotli.compress(file); + + const newResponse = await new Response(compressed); + // const newResponse = await new Response(file); newResponse.headers.set('Cache-Control', 'no-transform'); + newResponse.headers.set('Content-Encoding', 'br'); + if (filename.endsWith('.js')) { newResponse.headers.set('content-type', 'application/javascript') @@ -89,6 +97,15 @@ interface HelloMessage { known_users: string[] } +interface Hello2Message { + type: string + user_id: string + user_name: string + peer_id: string + peer_name: string + is_bootstrap_peer: boolean + // peer_description:RTCSessionDescription +} // interface PeerState { // socket:WebSocket; @@ -96,6 +113,7 @@ interface HelloMessage { // } // const peerStates:Map = new Map(); +const bootstrapPeers: Set = new Set(); const userPeers: Map> = new Map(); const peerSockets: Map = new Map(); const socketPeers: Map = new Map(); @@ -104,6 +122,31 @@ const socketPeers: Map = new Map(); // } +function hello2Handler(m:Hello2Message, socket:WebSocket) { + // bootstrapPeers.add(m.) + console.log(`[>hello2]: peer ${colorID(m.peer_id)}:${m.peer_name}, user ${colorID(m.user_id)}:${m.user_name}`); + + if (m.is_bootstrap_peer) { + bootstrapPeers.add(m.peer_id); + console.log(`This is a bootstrap peer. bootstrap peers:${[...bootstrapPeers.values()]}`); + } + + if (!userPeers.has(m.user_id)) { + userPeers.set(m.user_id, new Set()); + } + userPeers.get(m.user_id)?.add(m.peer_id); + peerSockets.set(m.peer_id, socket); // TODO:MAYBEBUG - what happens with multiple windows each with their own websocket? + socketPeers.set(socket, m.peer_id); + + if (!m.is_bootstrap_peer) { + + return JSON.stringify({ type: 'hello2', bootstrapPeers: [...bootstrapPeers.values()] }); + } + + return JSON.stringify({type:'hello2', message:'hello2 bootstrap peer!'}); + +} + function helloHandler(m: HelloMessage, socket: WebSocket) { console.log(`Received hello from peer ${colorID(m.peer_id)}:${m.peer_name}, user ${colorID(m.user_id)}:${m.user_name}`); @@ -233,7 +276,8 @@ function connectWebsocket(request: Request) { return; } console.log("Websocket close:", colorID(peerID), `code:${event.code} reason:${event.reason} wasClean: ${event.wasClean}`); - + + bootstrapPeers.delete(peerID); peerSockets.delete(peerID); deletePeerFromUserPeers(peerID); }); @@ -303,6 +347,7 @@ async function main() { messageDispatch.set('ping', pingHandler); messageDispatch.set('hello', helloHandler); + messageDispatch.set('hello2', hello2Handler); messageDispatch.set('peer_message', peerMessageHandler); Deno.serve({ diff --git a/ranting.md b/ranting.md index a5ecbfd..0738229 100644 --- a/ranting.md +++ b/ranting.md @@ -3,7 +3,7 @@ They can delete your data and the value of your data [like this](https://twitter # 0. Some ranting and a blueprint for the future. -I'm going to outline a few things that I think are really bad patterns wiht current software and creators ecosystems. Them I'm gonna tell you what I think we should do about it. +I'm going to outline a few things that I think are really bad patterns with current software and creators ecosystems. Then I'm gonna tell you what I think we should do about it. # 1. You don't own anything For a long time, i've been increasingly frustrated with software that I have to use on a daily basis. This is due to a number of factors: @@ -28,7 +28,7 @@ Today even your phone is incredibly fast and could search hundreds of megs of te For downloadable software, the pitch was that instead of getting a single version of the software, you would now get all updates as long as you continued to subscribe, and that ongoing paymets would fund ongoing development and innovation. -If you tended to upgrade to new versions, that *seems* to be pretty much equivalent, but there are a couple of hidden problems that eventually came to dominate this model. Firstly, for things like Photoshop, the pace of innovation pretty much plataued. Yes there are aamzing new AI tools in the most recent versions of PS, but if you don't use those new tools and are just a traditional user, the appliaction hasn't really changed in a decade. Secondly, Even if the price were equivalent, if you stop paying, then you lose access. So that's not equivalent at all. +If you tended to upgrade to new versions, that *seems* to be pretty much equivalent, but there are a couple of hidden problems that eventually came to dominate this model. Firstly, for things like Photoshop, the pace of innovation pretty much plataued. Yes there are amazing new AI tools in the most recent versions of PS, but if you don't use those new tools and are just a traditional user, the appliaction hasn't really changed in a decade. Secondly, Even if the price were equivalent, if you stop paying, then you lose access. So that's not equivalent at all. Ultimately, this wasn't about delivering software innovation. It was about maximizing profits for the companies that make the software. If you need to keep subscribing forever, they can turn what used to be a one-time $200 purchase, into a lifetime of payment for new features, regardless if you want them or not. @@ -48,7 +48,7 @@ In the olden days, you could either listen to the radio, or go to a store and bu ## Modern day Today we can listen to pretty much any track we like from any artist instantly by using a streaming service like Spotify or Apple Music or by finding music on YouTube. This is truly like a superpower and completely mindblowing compared to how we used to listen to music! -The downside is that in order to provide this service, all the music has to be uploaded to a central service that a company owns, and the company charges a fee to stream the music to users, giving the rest to the musicians. The free that the streaming services have been charging has been increasing ever since they launched meaning that over time, the wealth is being moved from the musicians who actually create the music to the companies who stream it and now have a monopoly on those streaming services. They also gatekeep who can get onto the services. +The downside is that in order to provide this service, all the music has to be uploaded to a central service that a company owns, and the company charges a fee to stream the music to users, giving the some small part to the musicians. The fee that the streaming services have been charging has been increasing ever since they launched meaning that over time, the wealth is being moved from the musicians who actually create the music to the companies who stream it and now have a monopoly on those streaming services. They also gatekeep who can get onto the services. ```javascript function foo() { diff --git a/src/IDUtils.ts b/src/IDUtils.ts new file mode 100644 index 0000000..9d6fde4 --- /dev/null +++ b/src/IDUtils.ts @@ -0,0 +1,13 @@ +function uuidv4() { + return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c: any) => + (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) + ); +} + +export function generateID() { + if (self.crypto.hasOwnProperty("randomUUID")) { + return self.crypto.randomUUID(); + } + + return uuidv4(); +} \ No newline at end of file diff --git a/src/PeerManager.ts b/src/PeerManager.ts new file mode 100644 index 0000000..0fc9cc5 --- /dev/null +++ b/src/PeerManager.ts @@ -0,0 +1,544 @@ +// connect to WS server, send info, connecto to bootstrap peer +// once connected to bootstrap peer, + +// Goal, connect to bootstrap peer, ask bootstrap peer for peers that have posts from users that we care about. get peers, connect to those peers, sync. +// how? do "perfect negotiation" with bootstrap peer. All logic here moves to BP. + +import { generateID } from "IDUtils"; + +// Use a broadcast channel to only have one peer manager for multiple tabs, +// then we won't need to have a session ID as all queries for a peerID will be coming from the same peer manager + +export class PeerManager { + routingTable: Map; + + private peers: Map; + private signaler: Signaler; + searchQueryFunctions: Map = new Map(); + RPC_remote: Map = new Map(); + rpc: { [key: string]: Function } = {}; + isBootstrapPeer: boolean = false; + bootstrapPeerConnection: PeerConnection | null = null; + + async onConnected(bootstrapPeerID: string) { + this.bootstrapPeerConnection = await this.connect(bootstrapPeerID); + } + + constructor(userID: string, peerID: string, isBootstrapPeer: boolean) { + this.isBootstrapPeer = isBootstrapPeer; + this.peers = new Map(); + this.routingTable = new Map(); + + + this.signaler = new Signaler(userID, peerID, isBootstrapPeer, this.onConnected.bind(this)); + + // Testing + let dummyPeer = new PeerConnection(this, "dummy_peer", this.signaler); + this.peers.set("dummy_peer", dummyPeer); + } + + async connect(remotePeerID: string) { + // Connect to the peer that has the peer id peerID + let peerConnection = new PeerConnection(this, remotePeerID, this.signaler); + await peerConnection.connect(); + this.peers.set(remotePeerID, peerConnection); + return peerConnection; + } + + async disconnect(remotePeerID: string) { + let peer = this.peers.get(remotePeerID); + + if (!peer) { + console.log(`PeerManager.disconnect: couln't find peer ${remotePeerID}`); + return; + } + + await peer.disconnect(); + this.peers.delete(remotePeerID); + } + + async call(peerID: string, functionName: string, args: any) { + let peer = this.peers.get(peerID); + + if (!peer) { + console.log(`Can't find peer ${peerID}`); + return; + } + + return await peer.call(functionName, args); + } + + callFromRemote(functionName: string, args: any) { + let func = this.RPC_remote.get(functionName); + + if (!func) { + throw new Error(); + } + + return func(args); + } + + registerRPC(functionName: string, func: Function) { + this.rpc[functionName] = (peerID: string, args: any) => { + return this.call(peerID, functionName, args); + }; + this.RPC_remote.set(functionName, func); + } + + registerSearchQuery(searchType: string, queryFunction: Function) { + this.searchQueryFunctions.set(searchType, queryFunction); + } + + async search(type: string, message: any) { + let promises = []; + for (let peer of this.peers.values()) { + promises.push(peer.call(type, message)); + } + + return await Promise.allSettled(promises); + } + + onMessage(remotePeerID: string, message: any) { + console.log(remotePeerID, message); + } +} + +function log(...args: any[]): void { + for (let arg of args) { + console.log("[LOG]", arg); + } +} + +interface Message { + type: string; + from_peer: string; + to_peer: string; + from_username: string; + from_peername: string; + peer_message: any; +} + +// Initially this wil be the bootstrap peer, We'll keep a connection to it and it will keep a list of all connected peers. +// Eventually we will replace this with connecting via other peers. +class Signaler { + websocket: WebSocket; + + sessionID: string; + userID: string; + peerID: string; + bootstrapPeerID: string = ""; + private isBootstrapPeer: boolean = false; + private onConnected: Function; + + constructor(userID: string, peerID: string, isBootstrapPeer: boolean, onConnected: Function) { + this.onConnected = onConnected; + this.isBootstrapPeer = isBootstrapPeer; + this.sessionID = generateID(); + this.userID = userID; + this.peerID = peerID; + + + try { + this.websocket = new WebSocket( + `wss://${window.location.hostname}:${window.location.port}/ws`, + ); + } catch (error: any) { + throw new Error(error.message); + } + + this.websocket.onopen = async (event) => { + log("signaler:ws:onopen"); + await this.sendHello2(); + }; + + this.websocket.onmessage = this.onMessage.bind(this); + } + + sendPeerMessage(remotePeerID: string, peerMessage: { type: string; description: RTCSessionDescription; }) { + this.send({ + type: "peer_message", + from: this.peerID, + to: remotePeerID, + from_username: "blah user", + from_peername: "blah peer", + message: peerMessage + }) + + // let responseMessage = { type: "peer_message", + // from: app.peerID, + // to: data.from, + // from_username: app.username, + // from_peername: app.peername, + // message: { type: "get_posts_for_user", post_ids: postIds, user_id: message.user_id } } + + } + + + async sendHello2() { + this.send({ + type: "hello2", + user_id: this.userID, + // user_name: app.username, + peer_id: this.peerID, + session_id: this.sessionID, + // peer_name: app.peername, + is_bootstrap_peer: this.isBootstrapPeer, + // peer_description: this.rtcPeerDescription + }); + } + + connect() { + } + + onMessage(event: MessageEvent) { + let messageJSON = event.data; + let message: any = null; + + try { + message = JSON.parse(messageJSON); + } catch (e) { + console.log(e); + throw new Error(); + } + + console.log("->signaler:", message); + + if (message.type === "hello2") { + + if (!this.isBootstrapPeer) { + this.bootstrapPeerID = message.bootstrapPeers[0]; + } + + this.onConnected(this.bootstrapPeerID); + } + } + + send(message: any) { + let messageJSON = ""; + + try { + messageJSON = JSON.stringify(message); + } catch (e) { + console.log(e); + return; + } + + console.log("<-signaler:", message); + + this.websocket.send(messageJSON); + } + + // sendPeerMessage +} + +class PeerConnection { + private remotePeerID: string; + private signaler: Signaler; + private peerManager: PeerManager; + private dataChannel: RTCDataChannel | null = null; + private messageHandlers: Map = new Map(); + + // private makingOffer:boolean = false; + // private ignoreOffer:boolean = false; + + rtcPeer: RTCPeerConnection | null = null; + + static config = { + iceServers: [ + { urls: "stun:ddln.app" }, + // { urls: "turn:ddln.app", username: "a", credential: "b" }, + { urls: "stun:stun.l.google.com" }, // keeping this for now as my STUN server is not return ipv6 + // { urls: "stun:stun1.l.google.com" }, + // { urls: "stun:stun2.l.google.com" }, + // { urls: "stun:stun3.l.google.com" }, + // { urls: "stun:stun4.l.google.com" }, + ], + }; + + pendingRPCs: Map< + string, + { resolve: Function; reject: Function; functionName: string } + > = new Map(); + messageSuperlog: boolean = true; + + async RPCHandler(message: any) { + } + + constructor( + peerManager: PeerManager, + remotePeerID: string, + signaler: Signaler, + ) { + this.peerManager = peerManager; + this.remotePeerID = remotePeerID; + this.signaler = signaler; + } + + async connect() { + this.rtcPeer = new RTCPeerConnection(PeerConnection.config); + this.dataChannel = this.rtcPeer.createDataChannel("ddln_main"); + + if (this.rtcPeer === null) { + return; + } + + // this.rtcPeer.onicecandidate = ({ candidate }) => this.signaler.send(JSON.stringify({ candidate })); + this.rtcPeer.onicecandidate = ({ candidate }) => console.log(candidate); + + + this.rtcPeer.onnegotiationneeded = async (event) => { + log("on negotiation needed fired"); + + if (!this.rtcPeer) { + throw new Error(); + } + + let makingOffer = false; + + try { + makingOffer = true; + await this.rtcPeer.setLocalDescription(); + + if (!this.rtcPeer.localDescription) { + return; + } + + this.signaler.sendPeerMessage(this.remotePeerID, { type: "rtcDescription", description: this.rtcPeer.localDescription }); + } catch (err) { + console.error(err); + } finally { + makingOffer = false; + } + }; + } + + async disconnect() { + } + + send(message: any) { + this.messageSuperlog && console.log("<-", message.type, message); + + let messageJSON = JSON.stringify(message); + // this.dataChannel?.send(); + + this.onMessage(messageJSON); + } + + call(functionName: string, args: any) { + let transactionID = generateID(); // make this faster as we will only ever have a small number of in-flight queries on a peer + // Think about a timeout here to auto reject it after a while. + let promise = new Promise((resolve, reject) => { + this.pendingRPCs.set(transactionID, { resolve, reject, functionName }); + // setTimeout(() => reject("bad"), 1000); + }); + + let message = { + type: "rpc_call", + transaction_id: transactionID, + function_name: functionName, + args: args, + }; + + this.send(message); + + return promise; + } + + onMessage(messageJSON: any) { + + let message: any = {}; + try { + message = JSON.parse(messageJSON); + } catch (e) { + console.log("PeerConnection.onMessage:", e); + } + + this.messageSuperlog && console.log("->", message.type, message); + let type = message.type; + + if (type === "rpc_response") { + let pendingRPC = this.pendingRPCs.get(message.transaction_id); + + if (!pendingRPC) { + throw new Error(); + } + + pendingRPC.resolve(message.response); + } + + if (type === "rpc_call") { + + let response = this.peerManager.callFromRemote(message.function_name, message.args); + + let responseMessage = { type: 'rpc_response', transaction_id: message.transaction_id, response: response }; + + this.send(responseMessage); + + } + + // this.peerManger.onMessage(this.remotePeerID, message); + } +} + +// export class PeerConnection2 { + +// id: string; + +// private makingOffer:boolean = false; +// private ignoreOffer:boolean = false; + +// rtcPeer: RTCPeerConnection; + +// signaler:WebSocket; + +// static config = { +// iceServers: [ +// { urls: "stun:stun.l.google.com" }, +// { urls: "stun:stun1.l.google.com" }, +// { urls: "stun:stun2.l.google.com" }, +// { urls: "stun:stun3.l.google.com" }, +// { urls: "stun:stun4.l.google.com" }, +// ], +// }; + +// constructor(remotePeerID: string, signaler:WebSocket) { +// this.id = remotePeerID; + +// this.rtcPeer = new RTCPeerConnection(PeerConnection2.config); + +// this.signaler = signaler;; + +// this.rtcPeer.onnegotiationneeded = async () => { +// try { +// this.makingOffer = true; +// await this.rtcPeer.setLocalDescription(); +// signaler.send(JSON.stringify({ description: this.rtcPeer.localDescription })); +// } catch (err) { +// console.error(err); +// } finally { +// this.makingOffer = false; +// } +// }; + +// this.rtcPeer.onicecandidate = ({ candidate }) => signaler.send(JSON.stringify({ candidate })); + +// this.ignoreOffer = false; +// } + +// onSignallerMessage = async ({ data: { description, candidate } }: MessageEvent) => { +// try { +// if (description) { +// // const offerCollision = +// // description.type === "offer" && +// // (this.makingOffer || this.rtcPeer.signalingState !== "stable"); + +// // this.ignoreOffer = !polite && offerCollision; +// if (this.ignoreOffer) { +// return; +// } + +// await this.rtcPeer.setRemoteDescription(description); +// if (description.type === "offer") { +// await this.rtcPeer.setLocalDescription(); +// this.signaler.send(JSON.stringify({ description: this.rtcPeer.localDescription })); +// } +// } else if (candidate) { +// try { +// await this.rtcPeer.addIceCandidate(candidate); +// } catch (err) { +// if (!this.ignoreOffer) { +// throw err; +// } +// } +// } +// } catch (err) { +// console.error(err); +// } +// }; + +// } + +// // const config = { +// // iceServers: [{ urls: "stun:stun.mystunserver.tld" }], +// // }; + +// // let polite = true; + +// // const signaler = new SignalingChannel(); +// // const signaler: any = {} +// // const rtcPeer = new RTCPeerConnection(config); + +// // // const constraints = { audio: true, video: true }; +// // const selfVideo = document.querySelector("video.selfview"); +// // const remoteVideo = document.querySelector("video.remoteview"); + +// // async function start() { +// // try { +// // const stream = await navigator.mediaDevices.getUserMedia(constraints); + +// // for (const track of stream.getTracks()) { +// // pc.addTrack(track, stream); +// // } +// // selfVideo.srcObject = stream; +// // } catch (err) { +// // console.error(err); +// // } +// // } + +// // rtcPeer.ontrack = ({ track, streams }) => { +// // track.onunmute = () => { +// // if (remoteVideo.srcObject) { +// // return; +// // } +// // remoteVideo.srcObject = streams[0]; +// // }; +// // }; + +// // makingOffer = false; + +// // rtcPeer.onnegotiationneeded = async () => { +// // try { +// // // makingOffer = true; +// // await rtcPeer.setLocalDescription(); +// // signaler.send({ description: rtcPeer.localDescription }); +// // } catch (err) { +// // console.error(err); +// // } finally { +// // makingOffer = false; +// // } +// // }; + +// // rtcPeer.onicecandidate = ({ candidate }) => signaler.send({ candidate }); + +// // let ignoreOffer = false; + +// // signaler.onmessage = async ({ data: { description, candidate } }: MessageEvent) => { +// // try { +// // if (description) { +// // const offerCollision = +// // description.type === "offer" && +// // // (makingOffer || rtcPeer.signalingState !== "stable"); + +// // ignoreOffer = !polite && offerCollision; +// // if (ignoreOffer) { +// // return; +// // } + +// // await rtcPeer.setRemoteDescription(description); +// // if (description.type === "offer") { +// // await rtcPeer.setLocalDescription(); +// // signaler.send({ description: rtcPeer.localDescription }); +// // } +// // } else if (candidate) { +// // try { +// // await rtcPeer.addIceCandidate(candidate); +// // } catch (err) { +// // if (!ignoreOffer) { +// // throw err; +// // } +// // } +// // } +// // } catch (err) { +// // console.error(err); +// // } +// // }; diff --git a/src/log.ts b/src/log.ts new file mode 100644 index 0000000..da68cb6 --- /dev/null +++ b/src/log.ts @@ -0,0 +1,28 @@ +let logLines: string[] = []; +let logLength = 30; +let logVisible = false; + +export function setLogVisibility(visible:boolean) { + logVisible = visible; +} + +export function renderLog() { + if (!logVisible) { + return; + } + + let log = document.getElementById("log"); + if (!log) { + throw new Error(); + } + log.innerText = logLines.join("\n"); +} +export function log(message: string) { + console.log(message); + logLines.push(`${new Date().toLocaleTimeString()}: ${message}`); + if (logLines.length > logLength) { + logLines = logLines.slice(logLines.length - logLength); + } + + renderLog(); +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 4164d28..173ef01 100644 --- a/src/main.ts +++ b/src/main.ts @@ -33,6 +33,7 @@ Restruucture the app around the data. App/WS split is messy. Clean it up. // import * as ForceGraph3D from "3d-force-graph"; import { openDatabase, getData, addData, addDataArray, clearData, deleteData, mergeDataArray, getAllData, checkPostIds, getAllIds, getPostsByIds } from "db"; +// import {PeerConnection} from "webRTC"; // declare let WebTorrent: any; @@ -279,6 +280,88 @@ interface PeerMessage { message: any; } +// class Signaler { +// websocket: WebSocket | null = null; + +// websocketPingInterval: number = 0; + + + +// connect() { +// if (this.websocket?.readyState === WebSocket.OPEN) { +// return; +// } + +// window.clearInterval(this.websocketPingInterval); +// if (this.websocket) { this.websocket.close() }; + +// try { +// this.websocket = new WebSocket(`wss://${window.location.hostname}:${window.location.port}/ws`); +// } catch (error: any) { +// console.log(error.message); +// return; +// } + +// this.websocket.onopen = async (event) => { +// log("ws:connected"); +// await this.sendHello(); + +// // If we're running as a headless peer, send a hello message every N seconds to refresh the posts we have. +// let helloRefreshIntervalPeriod = 120; +// if (app.isHeadless) { +// console.log("wsConnection: Setting hello refresh interval to ", helloRefreshIntervalPeriod) +// this.helloRefreshInterval = window.setInterval(() => { +// console.log("wsConnection: Hello refresh.") + +// if (!navigator.onLine) { +// return; +// } +// this.sendHello(); +// }, helloRefreshIntervalPeriod * 1000); +// } + +// this.websocketPingInterval = window.setInterval(() => { +// if (!navigator.onLine) { +// return; +// } +// this.send({ type: "ping", peer_id: this.peerID, peer_name: app.peername, user_id: app.userID, user_name: app.username }); +// }, 10_000) +// }; + +// this.websocket.onclose = (event) => { +// log("ws:disconnected"); +// // this.retry *= 2; +// log(`Retrying in ${this.retry} seconds`); +// window.setTimeout(() => { this.connect(); }, this.retry * 1000); +// }; + +// this.websocket.onmessage = (event) => { +// // log('ws:<-' + event.data.slice(0, 240)); +// let data = JSON.parse(event.data); + +// let { type } = data; + +// let handler = this.messageHandlers.get(type); +// if (!handler) { +// console.warn(`Got a message we can't handle:`, type); +// return; +// } + +// handler(data); + +// }; + +// this.websocket.onerror = (event) => { +// log('ws:error: ' + event); +// }; +// } +// } + +// disconnect() { +// this.websocket?.close(); +// } +// } + class wsConnection { websocket: WebSocket | null = null; userID = ""; @@ -304,12 +387,19 @@ class wsConnection { this.messageHandlers.set('pong', this.pongHandler); this.messageHandlers.set('peer_message', this.peerMessageHandler.bind(this)); + + // this.peerMessageHandlers.set('get_post_ids_for_user', this.getPostIdsForUserHandler.bind(this)); this.peerMessageHandlers.set('get_post_ids_for_user_response', this.getPostIdsForUserResponseHandler.bind(this)); this.peerMessageHandlers.set('get_posts_for_user', this.getPostsForUserHandler.bind(this)); this.peerMessageHandlers.set('get_posts_for_user_response', this.getPostsForUserReponseHandler.bind(this)); + this.peerMessageHandlers.set('send_webrtc_offer', this.sendWebRTCOfferHandler.bind(this)); + this.peerMessageHandlers.set('send_webrtc_offer_response', this.getPostIdsForUserResponseHandler.bind(this)); + + + window.addEventListener('beforeunload', () => this.disconnect()); this.connect(); @@ -340,6 +430,10 @@ class wsConnection { pongHandler(data: any) { } + async sendWebRTCOfferHandler(data:any) { + + } + async getPostIdsForUserResponseHandler(data: any) { // log(`getPostsForUserResponse: ${data}`) @@ -1020,6 +1114,8 @@ class App { this.render(); } + + // What happens with multiple tabs/connections from the same peer ID? I don't think this works, we also need a session ID for each connection getPeerID() { let id = localStorage.getItem("peer_id"); @@ -1540,7 +1636,36 @@ class App { } async main() { + let urlParams = (new URL(window.location.href)).searchParams; + if (urlParams.has('log')) { + this.showInfo(); + } + let peer:RTCPeerConnection|null = null; +// if (window.RTCPeerConnection) { + peer = new RTCPeerConnection({ + iceServers: [ + { urls: "stun:ddln.app"}, + { urls: "turn:ddln.app", username:"a", credential:"b"}, + { urls: "stun:stun.l.google.com" }, // keeping this for now as my STUN server is not return ipv6 + // { urls: "stun:stun1.l.google.com" }, + // { urls: "stun:stun2.l.google.com" }, + // { urls: "stun:stun3.l.google.com" }, + // { urls: "stun:stun4.l.google.com" }, + ] + }); + + peer.createDataChannel('boop'); + + peer.onicecandidate = ({ candidate }) => {log(`WRTC:${candidate?.address} ${candidate?.protocol} ${candidate?.type} ${(candidate as any)?.url}`)}; + peer.onnegotiationneeded = (event) => {console.log("on negotiation needed: ", event)} + + peer.createOffer().then((description)=>{ + peer.setLocalDescription(description) + log("RTC: " + description.sdp + description.type); + }); + + // } // await this.exportPostsForUser('b38b623c-c3fa-4351-9cab-50233c99fa4e'); @@ -1579,11 +1704,6 @@ class App { document.getElementById('connectURL')!.innerHTML = `connect`; - let urlParams = (new URL(window.location.href)).searchParams; - if (urlParams.has('log')) { - this.showInfo(); - } - if (urlParams.has('headless')) { this.isHeadless = true; } diff --git a/src/main2.ts b/src/main2.ts new file mode 100644 index 0000000..211c4b5 --- /dev/null +++ b/src/main2.ts @@ -0,0 +1,2114 @@ +// TODO: virtual list, only rerender what's needed so things can keep playing. + + + +/* +Problems + 1. Can't delete, very annoying + Tombstones. Send all IDs and all Tombstones. Ask only for posts that we don't get a tombstone for. Don't send posts we have a tombstone for? + + Posts don't propagate, you need to refresh to see new posts. + Broadcast when we post to all peers we know about. + + 3. Posting is slow because too long to render + 2. Can't follow people + 4. Can't like or reply to posts + +user + posts + media + tombstones + following + profile + name + description + profile pic + + +Restruucture the app around the data. App/WS split is messy. Clean it up. + +*/ + + +// import * as ForceGraph3D from "3d-force-graph"; +import { openDatabase, getData, addData, addDataArray, clearData, deleteData, mergeDataArray, getAllData, checkPostIds, getAllIds, getPostsByIds } from "db"; +import { generateID } from "IDUtils"; +import { PeerManager } from "PeerManager"; + +// import {PeerConnection} from "webRTC"; + +// declare let WebTorrent: any; + +// declare let ForceGraph3D: any; +declare let marked: any; +declare let QRCode: any; +// let posts:any; +// let keyBase = "dandelion_posts_v1_" +// let key:string = ""; + +// interface PostTimestamp { +// year: number, +// month: number, +// day: number, +// hour: number, +// minute: number, +// second: number, +// } + +function waitMs(durationMs: number) { + return new Promise(resolve => setTimeout(resolve, durationMs)); +} + +function uuidToBytes(uuid: string): Uint8Array { + return new Uint8Array(uuid.match(/[a-fA-F0-9]{2}/g)!.map((hex) => parseInt(hex, 16))); +} + +// Base58 character set +const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; +// Base58 encoding +// Base58 encoding +function encodeBase58(buffer: Uint8Array): string { + let carry; + const digits = [0]; + + for (const byte of buffer) { + carry = byte; + for (let i = 0; i < digits.length; i++) { + carry += digits[i] << 8; + digits[i] = carry % 58; + carry = Math.floor(carry / 58); + } + while (carry > 0) { + digits.push(carry % 58); + carry = Math.floor(carry / 58); + } + } + + let result = ''; + for (const digit of digits.reverse()) { + result += BASE58_ALPHABET[digit]; + } + + // Handle leading zero bytes + for (const byte of buffer) { + if (byte === 0x00) { + result = BASE58_ALPHABET[0] + result; + } else { + break; + } + } + + return result; +} + +// Convert UUID v4 to Base58 +function uuidToBase58(uuid: string): string { + const bytes = uuidToBytes(uuid); + return encodeBase58(bytes); +} + + +function logID(ID: string) { + return ID.substring(0, 5); +} + + +// function log(message:string) { +// console.log(message); +// let log = document.getElementById("log"); +// let newlog = document.createElement('span'); +// newlog.innerHTML = `
${message}
`; +// log?.appendChild(newlog); + +// } + +let logLines: string[] = []; +let logLength = 30; +let logVisible = false; +function renderLog() { + if (!logVisible) { + return; + } + + let log = document.getElementById("log"); + if (!log) { + throw new Error(); + } + log.innerText = logLines.join("\n"); +} +function log(message: string) { + console.log(message); + logLines.push(`${new Date().toLocaleTimeString()}: ${message}`); + if (logLines.length > logLength) { + logLines = logLines.slice(logLines.length - logLength); + } + + renderLog(); +} + + + +interface StoragePost { + data: Post; +} + +class Post { + post_timestamp: Date; + post_id: string; + author: string; + author_id: string; + text: string; + image_data: ArrayBuffer | null; + + + importedFrom: "twitter" | null; + importSource: any; + + constructor( + author: string, + author_id: string, + text: string, + post_timestamp: Date, + imageData: ArrayBuffer | null = null, + importedFrom: "twitter" | null = null, + importSource: any = null) { + + this.post_timestamp = post_timestamp; + this.post_id = generateID(); + + this.author = author; + this.author_id = author_id; + this.text = text; + this.image_data = imageData; + + this.importedFrom = importedFrom; + this.importSource = importSource; + } +} + +window.addEventListener('scroll', () => { + // Total height of the document + const totalPageHeight = document.body.scrollHeight; + + // Current scroll position + const scrollPoint = window.scrollY + window.innerHeight; + + // Check if scrolled to bottom + if (scrollPoint >= totalPageHeight) { + console.log('Scrolled to the bottom!'); + console.log(scrollPoint, totalPageHeight); + } + +}); + + + +// let peer = await new PeerConnection(peer_id); + +// let connectionReply = await wsConnection.send('hello'); +// for (let peer of connectionReply) { +// let peerConnection = await wsConnection.send('connect', peer.id); +// if (peerConnection) { +// this.peers.push(peerConnection); +// let postIDs = await peerConnection.getPostIDs(); +// let postsWeDontHave = this.diffPostIDs(postIDs); + +// let newPosts = await peerConnection.getPosts(postsWeDontHave); + +// this.addPosts(newPosts); + +// } +// } + +async function bytesToBase64DataUrl(bytes: Uint8Array, type = "application/octet-stream") { + return await new Promise((resolve, reject) => { + const reader = Object.assign(new FileReader(), { + onload: () => resolve(reader.result), + onerror: () => reject(reader.error), + }); + reader.readAsDataURL(new File([bytes], "", { type })); + }); +} + +async function arrayBufferToBase64(buffer: ArrayBuffer) { + var bytes = new Uint8Array(buffer); + return (await bytesToBase64DataUrl(bytes) as string).replace("data:application/octet-stream;base64,", ""); +} + +async function base64ToArrayBuffer(base64String: string) { + let response = await fetch("data:application/octet-stream;base64," + base64String); + let arrayBuffer = await response.arrayBuffer(); + return arrayBuffer; +} + +async function compressString(input: string) { + // Convert the string to a Uint8Array + const textEncoder = new TextEncoder(); + const inputArray = textEncoder.encode(input); + + // Create a CompressionStream + const compressionStream = new CompressionStream('gzip'); + const writer = compressionStream.writable.getWriter(); + + // Write the data and close the stream + writer.write(inputArray); + writer.close(); + + // Read the compressed data from the stream + const compressedArray = await new Response(compressionStream.readable).arrayBuffer(); + + // Convert the compressed data to a Uint8Array + return new Uint8Array(compressedArray); +} + +interface PeerMessage { + type: string; + from: string; + to: string; + from_peername: string; + from_username: string; + message: any; +} + +// class Signaler { +// websocket: WebSocket | null = null; + +// websocketPingInterval: number = 0; + + + +// connect() { +// if (this.websocket?.readyState === WebSocket.OPEN) { +// return; +// } + +// window.clearInterval(this.websocketPingInterval); +// if (this.websocket) { this.websocket.close() }; + +// try { +// this.websocket = new WebSocket(`wss://${window.location.hostname}:${window.location.port}/ws`); +// } catch (error: any) { +// console.log(error.message); +// return; +// } + +// this.websocket.onopen = async (event) => { +// log("ws:connected"); +// await this.sendHello(); + +// // If we're running as a headless peer, send a hello message every N seconds to refresh the posts we have. +// let helloRefreshIntervalPeriod = 120; +// if (app.isHeadless) { +// console.log("wsConnection: Setting hello refresh interval to ", helloRefreshIntervalPeriod) +// this.helloRefreshInterval = window.setInterval(() => { +// console.log("wsConnection: Hello refresh.") + +// if (!navigator.onLine) { +// return; +// } +// this.sendHello(); +// }, helloRefreshIntervalPeriod * 1000); +// } + +// this.websocketPingInterval = window.setInterval(() => { +// if (!navigator.onLine) { +// return; +// } +// this.send({ type: "ping", peer_id: this.peerID, peer_name: app.peername, user_id: app.userID, user_name: app.username }); +// }, 10_000) +// }; + +// this.websocket.onclose = (event) => { +// log("ws:disconnected"); +// // this.retry *= 2; +// log(`Retrying in ${this.retry} seconds`); +// window.setTimeout(() => { this.connect(); }, this.retry * 1000); +// }; + +// this.websocket.onmessage = (event) => { +// // log('ws:<-' + event.data.slice(0, 240)); +// let data = JSON.parse(event.data); + +// let { type } = data; + +// let handler = this.messageHandlers.get(type); +// if (!handler) { +// console.warn(`Got a message we can't handle:`, type); +// return; +// } + +// handler(data); + +// }; + +// this.websocket.onerror = (event) => { +// log('ws:error: ' + event); +// }; +// } +// } + +// disconnect() { +// this.websocket?.close(); +// } +// } + + +// Connect websocket +// send hello +// get bootstrap peer ID +// WebRTC connect to bootstrap peer +// ask Bootstrap peer for peers that have users we care about. +// for now, bootstrap peer will connect to all peers and will tell us about them, moving all logic from the server to the BSP +// WebRTC Connect to peers that might have posts we need +// query those peers and do existing logic. + +class wsConnection { + websocket: WebSocket | null = null; + sessionID = ""; + userID = ""; + peerID = ""; + rtcPeerDescription: RTCSessionDescription | null = null; + UserIDsToSync: Set; + websocketPingInterval: number = 0; + helloRefreshInterval: number = 0; + retry = 10; + state = 'disconnected'; + // peers: Map = new Map(); + + messageHandlers: Map void> = new Map(); + peerMessageHandlers: Map void> = new Map(); + seenPeers: Map = new Map(); + + + constructor(userID: string, peerID: string, IDsToSync: Set, rtcPeerDescription: RTCSessionDescription) { + this.rtcPeerDescription = rtcPeerDescription; + this.sessionID = generateID(); + this.userID = userID; + this.peerID = peerID; + this.UserIDsToSync = new Set(IDsToSync); + + this.messageHandlers.set('hello', this.helloResponseHandler.bind(this)); + this.messageHandlers.set('hello2', this.hello2ResponseHandler.bind(this)); + this.messageHandlers.set('pong', this.pongHandler); + this.messageHandlers.set('peer_message', this.peerMessageHandler.bind(this)); + + + // + this.peerMessageHandlers.set('get_post_ids_for_user', this.getPostIdsForUserHandler.bind(this)); + this.peerMessageHandlers.set('get_post_ids_for_user_response', this.getPostIdsForUserResponseHandler.bind(this)); + + this.peerMessageHandlers.set('get_posts_for_user', this.getPostsForUserHandler.bind(this)); + this.peerMessageHandlers.set('get_posts_for_user_response', this.getPostsForUserReponseHandler.bind(this)); + + // this.peerMessageHandlers.set('send_webrtc_offer', this.sendWebRTCOfferHandler.bind(this)); + // this.peerMessageHandlers.set('send_webrtc_offer_response', this.getPostIdsForUserResponseHandler.bind(this)); + + + + window.addEventListener('beforeunload', () => this.disconnect()); + + this.connect(); + } + + // So we don't need custom logic everywhere we use this, I just wrapped it. + shouldSyncUserID(userID: string) { + if (app.isHeadless) { + return true; + } + + return this.UserIDsToSync.has(userID); + } + + async send(message: any) { + let json = "" + try { + json = JSON.stringify(message); + // console.log("*******", (await compressString(json)).byteLength, json.length); + } catch (e) { + console.log(e, "wsConnection send: Couldn't serialize message", message); + } + // log(`ws->${json.slice(0, 240)}`) + this.websocket!.send(json); + + } + + pongHandler(data: any) { + } + + + async sendWebRTCDescription(description: RTCSessionDescription | null) { + + console.log("description:", description); + this.send({ type: "rtc_session_description", description: description }); + } + + async getPostIdsForUserResponseHandler(data: any) { + // log(`getPostsForUserResponse: ${data}`) + + let message = data.message; + log(`Net: got ${message.post_ids.length} post IDs for user ${logID(message.user_id)} from peer ${logID(data.from)}`); + + + let startTime = app.timerStart(); + let postIds = await checkPostIds(message.user_id, message.post_ids); + log(`ID Check for user ${logID(message.user_id)} took ${app.timerDelta().toFixed(2)}ms`); + log(`Need ${postIds.length} posts for user ${logID(message.user_id)} from peer ${logID(data.from)}`); + + if (postIds.length === 0) { + return; + } + + log(`Net: Req ${postIds.length} posts for user ${logID(message.user_id)} from peer ${logID(data.from)}`) + let responseMessage = { type: "peer_message", from: app.peerID, to: data.from, from_username: app.username, from_peername: app.peername, message: { type: "get_posts_for_user", post_ids: postIds, user_id: message.user_id } } + + this.send(responseMessage); + } + + + + // static async compressArrayBuffer(data: ArrayBuffer): Promise { + // const compressionStream = new CompressionStream('gzip'); // You can also use 'deflate', 'deflate-raw', etc. + + // const compressedStream = new Response( + // new Blob([data]).stream().pipeThrough(compressionStream) + // ); + + // const compressedArrayBuffer = await compressedStream.arrayBuffer(); + + // return compressedArrayBuffer; + // } + postBlockList = new Set([ + '1c71f53c-c467-48e4-bc8c-39005b37c0d5', + '64203497-f77b-40d6-9e76-34d17372e72a', + '243130d8-4a41-471e-8898-5075f1bd7aec', + 'e01eff89-5100-4b35-af4c-1c1bcb007dd0', + '194696a2-d850-4bb0-98f7-47416b3d1662', + 'f6b21eb1-a0ff-435b-8efc-6a3dd70c0dca', + 'dd1d92aa-aa24-4166-a925-94ba072a9048' + ]); + + async getPostIdsForUserHandler(data: any) { + let message = data.message; + let postIds = await getAllIds(message.user_id) ?? []; + postIds = postIds.filter((postID: string) => !this.postBlockList.has(postID)); + if (postIds.length === 0) { + log(`Net: I know about user ${logID(message.user_id)} but I have 0 posts, so I'm not sending any to to peer ${logID(data.from)}`); + return; + } + log(`Net: Sending ${postIds.length} post Ids for user ${logID(message.user_id)} to peer ${logID(data.from)}`) + + let responseMessage = { type: "peer_message", from: app.peerID, to: data.from, from_username: app.username, from_peername: app.peername, message: { type: "get_post_ids_for_user_response", post_ids: postIds, user_id: message.user_id } } + this.send(responseMessage); + } + + async broadcastNewPost(userID: string, post: any) { + + let newPost = { ...post } + if (post.image_data) { + newPost.image_data = await arrayBufferToBase64(post.image_data); + } + + for (let [peerID, peerInfo] of this.seenPeers.entries()) { + log(`broadcastNewPost: sending new post to ${logID(peerID)}:${peerInfo.peerName}:${peerInfo.userName}`); + + this.sendPostsForUser(peerID, app.userID, [newPost]) + } + } + + + async sendPostsForUser(toPeerID: string, userID: string, posts: any) { + let responseMessage = { + type: "peer_message", + from: app.peerID, + to: toPeerID, + from_username: app.username, + from_peername: app.peername, + message: { + type: "get_posts_for_user_response", + posts: posts, + user_id: userID + } + } + + return this.send(responseMessage); + + } + + // Send posts to peer + async getPostsForUserHandler(data: any) { + let message = data.message; + let posts = await getPostsByIds(message.user_id, message.post_ids) ?? []; + + log(`Net: Sending ${posts.length} posts for user ${logID(message.user_id)} to peer ${logID(data.from)}`); + + app.timerStart(); + let output = []; + + console.log("Serializing images"); + for (let post of posts) { + let newPost = (post as any).data; + + if (newPost.image_data) { + // let compressedData = await wsConnection.compressArrayBuffer(newPost.image_data); + // console.log((newPost.image_data.byteLength - compressedData.byteLength) / 1024 / 1024); + + // TODO don't do this, use Blobs direclty! + // https://developer.chrome.com/blog/blob-support-for-Indexeddb-landed-on-chrome-dev + + newPost.image_data = await arrayBufferToBase64(newPost.image_data); + + } + + // let megs = JSON.stringify(newPost).length/1024/1024; + // console.log(`getPostsForUserHandler id:${newPost.post_id} post length:${megs}`); + output.push(newPost); + } + + let responseMessage = { type: "peer_message", from: app.peerID, to: data.from, from_username: app.username, from_peername: app.peername, message: { type: "get_posts_for_user_response", posts: output, user_id: message.user_id } } + + console.log("Sending posts"); + await this.sendPostsForUser(data.from, message.user_id, output); + let sendTime = app.timerDelta(); + log(`getPostsForUserHandler send took: ${sendTime.toFixed(2)}ms`); + + } + + + + // Got posts from peer + async getPostsForUserReponseHandler(data: any) { + app.timerStart(); + let message = data.message; + console.log(`Net: got ${message.posts.length} posts for user ${logID(message.user_id)} from peer ${logID(data.from)}`); + for (let post of message.posts) { + + // HACK: Some posts have insanely large images, so I'm gonna skip them. + // Once we support delete then we we could delete these posts in a sensible way. + if (this.postBlockList.has(post.post_id)) { + log(`Skipping blocked post: ${post.post_id}`); + continue; + } + + // HACK - some posts had the wrong author ID + if (message.user_id === app.userID) { + post.author_id = app.userID; + } + + post.post_timestamp = new Date(post.post_timestamp); + if (post.image_data) { + post.image_data = await base64ToArrayBuffer(post.image_data); + } + } + console.log(`Merging same user peer posts...`) + await mergeDataArray(message.user_id, data.message.posts); + + let receiveTime = app.timerDelta(); + + log(`getPostsForUserReponseHandler receive took: ${receiveTime.toFixed(2)}ms`); + + + if (message.user_id === app.getPreferentialUserID() || app.following.has(message.user_id)) { + app.render(); + } + } + + + + + async peerMessageHandler(data: PeerMessage) { + // log(`peerMessageHandler ${JSON.stringify(data)}`) + + this.seenPeers.set(data.from, { peerName: data.from_peername, userName: data.from_username }); + + let peerMessageType = data.message.type; + + let handler = this.peerMessageHandlers.get(peerMessageType); + + if (!handler) { + console.error(`got peer message type we don't have a handler for: ${peerMessageType}`); + return; + } + + handler(data); + } + + userBlockList = new Set([ + '5d63f0b2-a842-41bf-bf06-e0e4f6369271', + '5f1b85c4-b14c-454c-8df1-2cacc93f8a77', + // 'bba3ad24-9181-4e22-90c8-c265c80873ea' + ]) + + + // Hello2 + // Goal, connect to bootstrap peer, ask bootstrap peer for peers that have posts from users that we care about. get peers, connect to those peers, sync. + // how? do "perfect negotiation" with bootstrap peer. All logic here moves to BP. + + async sendHello2() { + this.send({ + type: "hello2", + user_id: this.userID, + user_name: app.username, + peer_id: this.peerID, + session_id: this.sessionID, + peer_name: app.peername, + is_bootstrap_peer: app.isBootstrapPeer, + peer_description: this.rtcPeerDescription + }); + } + + async sendHello() { + // TODO only get users you're following here. ✅ + let knownUsers = [...(await indexedDB.databases())].map(db => db.name?.replace('user_', '')).filter(userID => userID !== undefined); + knownUsers = knownUsers + .filter(userID => this.shouldSyncUserID(userID)) + .filter(userID => !this.userBlockList.has(userID)) + .filter(async userID => (await getAllIds(userID)).length > 0); // TODO:EASYOPT getting all the IDs is unecessary, replace it with a test to get a single ID. + + console.log('Net: Sending known users', knownUsers.map(userID => logID(userID ?? ""))); + return await this.send({ type: "hello", user_id: this.userID, user_name: app.username, peer_id: this.peerID, peer_name: app.peername, known_users: knownUsers }); + } + + hello2ResponseHandler(data: any) { + + } + + helloResponseHandler(data: any) { + + let users = []; + let receivedUsers = Object.entries(data.userPeers); + log(`Net: got ${receivedUsers.length} users from bootstrap peer.`) + + try { + let preferentialUserID = app.getPreferentialUserID(); + let currentUserPeers = data.userPeers[preferentialUserID]; + users.push([preferentialUserID, currentUserPeers]); + delete data.userPeers[preferentialUserID]; + } catch (e) { + console.log('helloResponseHandler', e); + } + + let getAllUsers = app.router.route !== App.Route.USER + if (getAllUsers) { + users = [...users, ...Object.entries(data.userPeers).filter(userID => this.shouldSyncUserID(userID[0]))]; + } + + // log(`Net: got ${users.length} users from bootstrap peer. \n${users.map((user)=>user[0]).join('\n')}`) + + for (let [userID, peerIDs] of users) { + if (this.userBlockList.has(userID)) { + console.log("Skipping user on blocklist:", userID) + continue; + } + + // this.peers.set(userID, [...peerIDs]); + + for (let peerID of [...peerIDs]) { + if (peerID === this.peerID) { + continue; + } + + log(`Net: Req post IDs for user ${logID(userID)} from peer ${logID(peerID)}`); + this.send({ + type: "peer_message", + from: this.peerID, + from_username: app.username, + from_peername: app.peername, + to: peerID, + message: { type: "get_post_ids_for_user", user_id: userID } + }) + } + } + } + + connect(): void { + if (this.websocket?.readyState === WebSocket.OPEN) { + return; + } + + window.clearInterval(this.websocketPingInterval); + if (this.websocket) { this.websocket.close() }; + + try { + this.websocket = new WebSocket(`wss://${window.location.hostname}:${window.location.port}/ws`); + } catch (error: any) { + console.log(error.message); + return; + } + + this.websocket.onopen = async (event) => { + log("ws:connected"); + await this.sendHello2(); + + // If we're running as a headless peer, send a hello message every N seconds to refresh the posts we have. + // let helloRefreshIntervalPeriod = 120; + // if (app.isHeadless) { + // console.log("wsConnection: Setting hello refresh interval to ", helloRefreshIntervalPeriod) + // this.helloRefreshInterval = window.setInterval(() => { + // console.log("wsConnection: Hello refresh.") + + // if (!navigator.onLine) { + // return; + // } + // this.sendHello(); + // }, helloRefreshIntervalPeriod * 1000); + // } + + this.websocketPingInterval = window.setInterval(() => { + if (!navigator.onLine) { + return; + } + this.send({ type: "ping", peer_id: this.peerID, peer_name: app.peername, user_id: app.userID, user_name: app.username }); + }, 10_000) + }; + + // this.websocket.onopen = async (event) => { + // log("ws:connected"); + // await this.sendHello(); + + // // If we're running as a headless peer, send a hello message every N seconds to refresh the posts we have. + // let helloRefreshIntervalPeriod = 120; + // if (app.isHeadless) { + // console.log("wsConnection: Setting hello refresh interval to ", helloRefreshIntervalPeriod) + // this.helloRefreshInterval = window.setInterval(() => { + // console.log("wsConnection: Hello refresh.") + + // if (!navigator.onLine) { + // return; + // } + // this.sendHello(); + // }, helloRefreshIntervalPeriod * 1000); + // } + + // this.websocketPingInterval = window.setInterval(() => { + // if (!navigator.onLine) { + // return; + // } + // this.send({ type: "ping", peer_id: this.peerID, peer_name: app.peername, user_id: app.userID, user_name: app.username }); + // }, 10_000) + // }; + + this.websocket.onclose = (event) => { + log("ws:disconnected"); + // this.retry *= 2; + log(`Retrying in ${this.retry} seconds`); + window.setTimeout(() => { this.connect(); }, this.retry * 1000); + }; + + this.websocket.onmessage = (event) => { + // log('ws:<-' + event.data.slice(0, 240)); + let data = JSON.parse(event.data); + + let { type } = data; + + let handler = this.messageHandlers.get(type); + if (!handler) { + console.warn(`Got a message we can't handle:`, type); + return; + } + + handler(data); + + }; + + this.websocket.onerror = (event) => { + log('ws:error: ' + event); + }; + } + + disconnect() { + this.websocket?.close(); + } +} + +class App { + username: string = ''; + peername: string = ''; + userID: string = ''; + peerID: string = ''; + following: Set = new Set(); + posts: StoragePost[] = []; + isHeadless: boolean = false; + isBootstrapPeer: boolean = false; + showLog: boolean = false; + markedAvailable = false; + limitPosts = 50; + websocket: wsConnection | null = null; + // vizGraph: any | null = null; + qrcode: any = null; + connectURL: string = ""; + firstRun = false; + peerManager: PeerManager | null = null; + + getPreferentialUserID() { + return this.router.userID.length !== 0 ? this.router.userID : this.userID; + } + + initMarkdown() { + if (typeof marked === "undefined") { + return; + } + + const renderer = new marked.Renderer(); + renderer.link = (href: any, title: string, text: string) => { + return `${text}`; + }; + marked.setOptions({ renderer: renderer }); + + this.markedAvailable = true; + } + + // arrayBufferToBase64(buffer: ArrayBuffer) { + // return new Promise((resolve, reject) => { + // const blob = new Blob([buffer], { type: 'application/octet-stream' }); + // const reader = new FileReader(); + + // reader.onloadend = () => { + // const dataUrl = reader.result as string; + // if (!dataUrl) { + // resolve(null); + // return; + // } + // const base64 = dataUrl.split(',')[1]; + // resolve(base64); + // }; + + // reader.onerror = (error) => { + // reject(error); + // }; + + // reader.readAsDataURL(blob); + // }); + // } + + async createTestData() { + let postsTestData = await (await fetch("./postsTestData.json")).json(); + + return postsTestData; + } + + time = 0; + + timerStart() { + this.time = performance.now(); + } + + timerDelta() { + return performance.now() - this.time; + } + + getFixedTweetText(entry: any) { + + + let fullText = entry.tweet.full_text; + + let linkMarkdown = ""; + for (const url of entry.tweet.entities.urls) { + linkMarkdown = `[${url.display_url}](${url.expanded_url})`; + fullText = fullText.replace(url.url, linkMarkdown); + } + + return fullText + } + + downloadBinary(data: ArrayBuffer, filename: string, mimeType: string = 'application/octet-stream') { + // Create a blob from the ArrayBuffer with the specified MIME type + const blob = new Blob([data], { type: mimeType }); + + // Create object URL from the blob + const url = window.URL.createObjectURL(blob); + + // Create temporary link element + const link = document.createElement('a'); + link.href = url; + link.download = filename; + + // Append link to body, click it, and remove it + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + + // Clean up the object URL + window.URL.revokeObjectURL(url); + } + + downloadJson(data: any, filename = 'data.json') { + const jsonString = JSON.stringify(data); + const blob = new Blob([jsonString], { type: 'application/json' }); + const url = window.URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = url; + link.download = filename; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + window.URL.revokeObjectURL(url); + } + + async importPostsForUser(userID: string, posts: string) { + + } + + async exportPostsForUser(userID: string) { + + let posts = await getAllData(userID); + + let output = []; + + console.log("Serializing images"); + for (let post of posts) { + let newPost = (post as any).data; + + if (newPost.image_data) { + newPost.image_data = await arrayBufferToBase64(newPost.image_data); + } + + output.push(newPost); + } + + let compressedData = await compressString(JSON.stringify(output)); + + const d = new Date(); + const timestamp = `${d.getFullYear() + }_${String(d.getMonth() + 1).padStart(2, '0') + }_${String(d.getDate()).padStart(2, '0') + }_${String(d.getHours()).padStart(2, '0') + }_${String(d.getMinutes()).padStart(2, '0') + }_${String(d.getSeconds()).padStart(2, '0')}`; + + + this.downloadBinary(compressedData, `ddln_${this.username}_export_${timestamp}.json.gz`); + } + + async importTweetArchive(userID: string, tweetArchive: any[]) { + log("Importing tweet archive") + let postsTestData: any[] = []; + + // let response = await fetch("./tweets.js"); + // let tweetsText = await response.text(); + // tweetsText = tweetsText.replace("window.YTD.tweets.part0", "window.tweetData"); + + // new Function(tweetsText)(); + + + // let tweets = JSON.parse(tweetJSON); + let count = 0; + + for (let entry of tweetArchive) { + // if (entry.tweet.hasOwnProperty("in_reply_to_screen_name") || entry.tweet.retweeted || entry.tweet.full_text.startsWith("RT")) { + // continue; + // } + + let mediaURL: string = entry.tweet?.entities?.media?.[0]?.media_url_https; + let isImage = false; + if (mediaURL) { + isImage = mediaURL.includes('jpg'); + } + + let imageData = null; + // if (isImage) { + // try { + // let response = await fetch(mediaURL); + // await waitMs(100); + // if (response.status === 200) { + // imageData = await response.arrayBuffer(); + // } + // console.log(imageData); + // } catch (e) { + // console.log(e); + // } + + // } + + let timeStamp = new Date(entry.tweet.created_at); + let tweetText = this.getFixedTweetText(entry); + let newPost = new Post('bobbydigitales', userID, tweetText, timeStamp, imageData, 'twitter', entry); + + postsTestData.push(newPost); + + count++; + if (count % 100 === 0) { + log(`Imported ${count} posts...`); + // render(postsTestData); + } + + // if (count == 100-1) { + // break; + // } + + } + return postsTestData; + } + + async createTestData3(userID: string) { + let posts = await (await (fetch('./posts.json'))).json(); + + return posts; + } + + async registerServiceWorker() { + if (!("serviceWorker" in navigator)) { + return; + } + + let registrations = await navigator.serviceWorker.getRegistrations(); + if (registrations.length > 0) { + console.log("Service worker already registered."); + return registrations[0]; + } + + navigator.serviceWorker + .register("/sw.js") + .then((registration) => { + console.log("Service Worker registered with scope:", registration.scope); + return registration; + }) + .catch((error) => { + console.error("Service Worker registration failed:", error); + }); + } + + async compressImage(imageData: ArrayBuffer, mimeType: string, quality = 0.5): Promise { + let uncompressedByteLength = imageData.byteLength; + log(`compressImage input:${mimeType} size:${(uncompressedByteLength / 1024).toFixed(2)}KBi quality:${quality}`); + + try { + // Convert ArrayBuffer to Blob + const blob = new Blob([imageData], { type: mimeType }); + + const bitmap = await createImageBitmap(blob, { + imageOrientation: 'none', + + // resizeWidth: desiredWidth, + // resizeHeight: desiredHeight, + // resizeQuality: 'high', + }); + + // const bitmap = await createImageBitmap(bitmapTemp, { + // imageOrientation: 'none', + + // resizeWidth: 600, + // resizeHeight: 800, + // // resizeHeight: (bitmapTemp.height / bitmapTemp.width) * 600, + // resizeQuality: 'high', + // }) + + //drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) + + + // Create a canvas and draw the image onto it + // let scale = 1/32; + // let scaledWidth = bitmap.width*scale; + // let scaledHeight = bitmap.height*scale; + + // let scale = 1/32; + + let scaledWidth = bitmap.width; + let scaledHeight = bitmap.height; + + let resizeThreshold = 600; + if (scaledWidth > resizeThreshold) { + scaledWidth = resizeThreshold; + scaledHeight = (bitmap.height / bitmap.width) * resizeThreshold; + } + + const canvas = document.createElement('canvas'); + canvas.width = scaledWidth; + canvas.height = scaledHeight; + const ctx = canvas.getContext('2d'); + ctx!.imageSmoothingEnabled = true; + ctx!.imageSmoothingQuality = 'high'; + canvas!.getContext('2d')!.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, scaledWidth, scaledHeight); + + + // Compress the image and get the result as an ArrayBuffer + const compressedBlob = await new Promise((resolve, reject) => + canvas.toBlob( + (blob) => (blob ? resolve(blob as Blob) : reject(new Error('Compression failed.'))), + 'image/jpeg', + quality + ) + ); + + + // TODO: Don't need to do this as we'll be storing blobs directly. + let compressedArrayBuffer = await (compressedBlob as Blob).arrayBuffer(); + let compressedByteLength = compressedArrayBuffer.byteLength; + + let percent = (uncompressedByteLength / compressedByteLength) + log(`compressImage: compressedSize:${(compressedArrayBuffer.byteLength / 1024).toFixed(2)}KBi ${percent.toFixed(2)}:1 compression`); + return compressedArrayBuffer; + } catch (e) { + console.error(e); + return null; + } + } + + async createNewPost(userID: string, postText: string, mediaData?: ArrayBuffer, mimeType?: "image/png" | "image/gif" | "image/jpg" | "image/jpeg" | "video/mp4") { + if ((typeof postText !== "string") || postText.length === 0) { + log("Not posting an empty string...") + return; + } + + if (mediaData && + (mimeType === 'image/jpg' || mimeType === 'image/jpeg' || mimeType === 'image/png') && + (mediaData as ArrayBuffer).byteLength > 500 * 1024) { + let compressedImage = await this.compressImage(mediaData as ArrayBuffer, mimeType, 0.9); + if (compressedImage) { + mediaData = compressedImage as ArrayBuffer; + } + } + + let post = new Post(this.username, userID, postText, new Date(), mediaData); + // this.posts.push(post); + // localStorage.setItem(key, JSON.stringify(posts)); + addData(userID, post); + + this.websocket?.broadcastNewPost(userID, post); + + + this.render(); + } + + getPeerID() { + let id = localStorage.getItem("peer_id"); + + if (!id) { + log(`Didn't find a peer ID, generating one`); + id = generateID(); + localStorage.setItem("peer_id", id); + } + + return id; + } + + getUserID() { + let id = localStorage.getItem("dandelion_id"); + + if (!id) { + log(`Didn't find a user ID, generating one`); + id = generateID(); + localStorage.setItem("dandelion_id", id); + } + + return id; + } + + animals = ['shrew', 'jerboa', 'lemur', 'weasel', 'possum', 'possum', 'marmoset', 'planigale', 'mole', 'narwhal']; + adjectives = ['snazzy', 'whimsical', 'jazzy', 'bonkers', 'wobbly', 'spiffy', 'chirpy', 'zesty', 'bubbly', 'perky', 'sassy']; + snakes = ['mamba', 'cobra', 'python', 'viper', 'krait', 'sidewinder', 'constrictor', 'boa', 'asp', 'anaconda', 'krait'] + + hashIdToIndices(id: string) { + let indices = []; + for (let char of id) { + if (char !== '0' && char !== '-') { + indices.push(parseInt(char, 16)); + if (indices.length == 2) { + break; + } + } + } + return [indices[0], indices[1]]; + } + + funkyName(id: string, listOne: string[], listTwo: string[]) { + let [one, two] = this.hashIdToIndices(id); + let first = listOne[one % this.adjectives.length]; + let second = listTwo[two % this.animals.length]; + return { first, second } + } + + getUsername() { + let username = localStorage.getItem("dandelion_username"); + + if (username && username !== "not_set") { + return username; + } + + let { first: adjective, second: animal } = this.funkyName(this.userID, this.adjectives, this.animals); + username = `${adjective}_${animal}` + localStorage.setItem("dandelion_username", username); + + return username; + } + + getPeername() { + let { first: adjective, second: snake } = this.funkyName(this.peerID, this.adjectives, this.snakes); + let peername = `${adjective}_${snake}` + return peername; + } + + setFont(fontName: string, fontSize: string) { + + let content = document.getElementById('content'); + + if (!content) { + return; + } + + content.style.fontFamily = fontName; + content.style.fontSize = fontSize; + + let textArea = document.getElementById('textarea_post'); + if (!textArea) { + return; + } + + textArea.style.fontFamily = fontName; + textArea.style.fontSize = fontSize; + } + + initOffline(connection: wsConnection) { + // Event listener for going offline + window.addEventListener('offline', () => { + log("offline") + }); + + // Event listener for going online + window.addEventListener('online', async () => { + log("online") + connection.connect(); + this.render(); + }); + + log(`Online status: ${navigator.onLine ? "online" : "offline"}`) + + } + + selectFile(contentType: string): Promise { + return new Promise(resolve => { + let input = document.createElement('input'); + input.type = 'file'; + // input.multiple = multiple; + input.accept = contentType; + + input.onchange = () => { + if (input.files == null) { + resolve(null); + return; + } + + let files = Array.from(input.files); + + // if (multiple) + // resolve(files); + // else + resolve(files[0]); + }; + + input.click(); + }); + } + + readFile(file: File): Promise { + // Always return a Promise + return new Promise((resolve, reject) => { + let content = ''; + const reader = new FileReader(); + // Wait till complete + reader.onloadend = function (e: any) { + content = e.target.result; + resolve(content); + }; + // Make sure to handle error states + reader.onerror = function (e: any) { + reject(e); + }; + reader.readAsText(file); + }); + } + + async lazyCreateQRCode() { + if (this.qrcode != null) { + return; + } + this.qrcode = await new QRCode(document.getElementById('qrcode'), { + text: this.connectURL, + width: 150, + height: 150, + colorDark: "#000000", + colorLight: "#ffffff", + correctLevel: QRCode.CorrectLevel.H + }); + } + + showInfo() { + let infoElement = document.getElementById('info'); + + if (infoElement === null) { + return; + } + infoElement.style.display == 'none' ? infoElement.style.display = 'block' : infoElement.style.display = 'none'; + logVisible = infoElement.style.display == 'block'; + renderLog(); + this.lazyCreateQRCode(); + (document.querySelector('#qrcode > img') as HTMLImageElement).classList.add('qrcode_image'); + (document.querySelector('#qrcode > canvas') as HTMLImageElement).classList.add('qrcode_image'); + + this.showLog = true; + + + } + + button(elementName: string) { + return document.getElementById(elementName) as HTMLButtonElement; + } + + div(elementName: string) { + return document.getElementById(elementName) as HTMLDivElement; + } + + initButtons(userID: string, posts: StoragePost[], registration: ServiceWorkerRegistration | undefined) { + // let font1Button = document.getElementById("button_font1") as HTMLButtonElement; + // let font2Button = document.getElementById("button_font2") as HTMLButtonElement; + // let importTweetsButton = document.getElementById("import_tweets") as HTMLButtonElement; + // let toggleDark = document.getElementById('toggle_dark') as HTMLButtonElement; + // let clearPostsButton = document.getElementById("clear_posts") as HTMLButtonElement; + // let updateApp = document.getElementById("update_app") as HTMLButtonElement; + // let ddlnLogoButton = document.getElementById('ddln_logo_button') as HTMLDivElement; + // let addPic = document.getElementById('button_add_pic') as HTMLDivElement; + // toggleDark.addEventListener('click', () => { + // document.documentElement.style.setProperty('--main-bg-color', 'white'); + // document.documentElement.style.setProperty('--main-fg-color', 'black'); + // }) + + let homeButton = this.div('home-button'); + homeButton.addEventListener('click', e => window.location.href = `${window.location.origin}/`) + + let profileButton = this.div('profile-button'); + profileButton.addEventListener('click', e => window.location.href = `${window.location.origin}/user/${this.userID}`) + + let monitorButton = this.div('monitor_button'); + monitorButton.addEventListener('click', async () => { + navContainer.classList.toggle('active'); + this.showInfo() + }); + + let navContainer = this.div('nav-container'); + let burgerMenuButton = this.div('burger-menu-button'); + burgerMenuButton.addEventListener('click', e => navContainer.classList.toggle('active')); + + let exportButton = this.button("export-button"); + exportButton.addEventListener('click', async e => { + + await this.exportPostsForUser(this.userID) + }); + + let composeButton = this.div('compose-button'); + composeButton.addEventListener('click', e => { + document.getElementById('compose')!.style.display = 'block'; + document.getElementById('textarea_post')?.focus(); + }); + + + let filePicker = document.getElementById('file-input') as HTMLInputElement; + filePicker?.addEventListener('change', async (event: any) => { + for (let file of filePicker.files as any) { + let buffer = await file.arrayBuffer(); + await this.createNewPost(this.userID, 'image...', buffer, file.type); + } + + // Reset so that if they pick the same image again, we still get the change event. + filePicker.value = ''; + }); + + let filePickerLabel = document.getElementById('file-input-label'); + filePickerLabel?.addEventListener('click', () => { + console.log("Add pic...") + }) + + + let usernameField = document.getElementById('username'); + usernameField?.addEventListener('input', (event: any) => { + this.username = event.target.innerText; + localStorage.setItem("dandelion_username", this.username); + }) + + // importTweetsButton.addEventListener('click', async () => { + // let file = await this.selectFile('text/*'); + + // console.log(file); + // if (file == null) { + // return; + // } + + // let tweetData = await this.readFile(file); + // tweetData = tweetData.replace('window.YTD.tweets.part0 = ', ''); + // const tweets = JSON.parse(tweetData); + + // let imported_posts = await this.importTweetArchive(userID, tweets); + // clearData(userID); + // // posts = posts.reverse(); + // addDataArray(userID, imported_posts); + // this.render(); + + // }); + + // clearPostsButton.addEventListener('click', () => { clearData(userID); posts = []; this.render() }); + + + let postButton = document.getElementById("button_post") as HTMLButtonElement; + let postText = document.getElementById("textarea_post") as HTMLTextAreaElement; + + if (!(postButton && postText)) { + throw new Error(); + } + + postText.addEventListener('paste', async (e) => { + const dataTransfer = e.clipboardData + const file = dataTransfer!.files[0]; + let buffer = await file.arrayBuffer(); + await this.createNewPost(this.userID, 'image...', buffer, file.type as any); + }); + + postButton.addEventListener("click", () => { + this.createNewPost(userID, postText.value); + postText.value = ""; + document.getElementById('compose')!.style.display = 'none'; + }); + + // updateApp.addEventListener("click", () => { + // registration?.active?.postMessage({ type: "update_app" }); + // }); + + + // ddlnLogoButton.addEventListener('click', async () => { + // this.showInfo() + // }); + + } + + async getPostsForFeed() { + + // get N posts from each user and sort them by date. + // This isn't really going to work very well. + // Eventually we'll need a db that only has followed user posts so we can get them chronologically + // + let posts: StoragePost[] = []; + for (let followedID of this.following.keys()) { + posts = posts.concat(await getData(followedID, new Date(2022, 8), new Date())); + // console.log(followedID); + } + + // @ts-ignore + posts = posts.sort((a, b) => a.post_timestamp - b.post_timestamp); + + return posts; + } + + async loadFollowersFromStorage(userID: string): Promise { + + // Rob + if (userID === 'b38b623c-c3fa-4351-9cab-50233c99fa4e') { + return [ + 'b38b623c-c3fa-4351-9cab-50233c99fa4e', + '6d774268-16cd-4e86-8bbe-847a0328893d', // Sean + '05a495a0-0dd8-4186-94c3-b8309ba6fc4c', // Martin + 'a0e42390-08b5-4b07-bc2b-787f8e5f1297', // BMO + 'bba3ad24-9181-4e22-90c8-c265c80873ea', // Harry + '8f6802be-c3b6-46c1-969c-5f90cbe01479', // Fiona + ] + } + + // Martin + if (userID === '05a495a0-0dd8-4186-94c3-b8309ba6fc4c') { + return [ + 'b38b623c-c3fa-4351-9cab-50233c99fa4e', + 'a0e42390-08b5-4b07-bc2b-787f8e5f1297', // BMO + ] + } + + // Fiona + if (userID === '8f6802be-c3b6-46c1-969c-5f90cbe01479') { + return [ + 'b38b623c-c3fa-4351-9cab-50233c99fa4e', // Rob + 'a0e42390-08b5-4b07-bc2b-787f8e5f1297', // BMO + '05a495a0-0dd8-4186-94c3-b8309ba6fc4c', // Martin + ] + } + + return ['a0e42390-08b5-4b07-bc2b-787f8e5f1297']; // Follow BMO by default :) + } + + async loadPostsFromStorage(userID: string, postID?: string) { + + this.timerStart(); + let posts: StoragePost[] = []; + + // if (postID) { + // posts = await gePostForUser(userID, postID); + // } + + posts = await getData(userID, new Date(2022, 8), new Date()); + + if (posts.length > 0) { + log(`Loaded ${posts.length} posts in ${this.timerDelta().toFixed(2)}ms`); + return posts; + } + + // posts = await createTestData2(userID); + + // log("Adding test data..."); + // addDataArray(userID, posts); + // return await getData(userID, new Date(2022, 8), new Date()); + } + + async listUsers() { + let knownUsers = [...(await indexedDB.databases())].map((db) => db.name?.replace('user_', '')); + if (knownUsers.length === 0) { + return; + } + + let preferredId = app.getPreferentialUserID() + for (let userID of knownUsers as string[]) { + // if (userID === preferredId) { + // continue; + // } + + // let ids = await getAllIds(userID); + // if (ids.length === 0) { + // console.log(`Purging user ${userID}`); + // indexedDB.deleteDatabase(`user_${userID}`); + // continue; + // } + + console.log(`${document.location.origin}/user/${userID}`); + + // console.log(`https://ddln.app/${this.username}/${uuidToBase58(userID)}`, userID); + } + + } + + + async initDB() { + let db = await openDatabase(this.userID); + } + + query_findPeersForUser(message: any) { + let havePostsForUser = true; + if (havePostsForUser) { + return this.peerID; + } + + return false; + } + + async testPeerManager() { + if (!this.peerManager) { + throw new Error(); + } + + this.peerManager.registerRPC('getPostIDsForUser', (args: any) => { + return [1, 2, 3, 4, 5] + }); + + let postIDs = await this.peerManager.rpc.getPostIDsForUser("dummy_peer", "bloop"); + + console.log("peerManager.rpc.getPostIDsForUser", postIDs); + + // this.peerManager.registerSearchQuery('find_peers_for_user', this.query_findPeersForUser); + + // let peers = await this.peerManager.search('find_peers_for_user', { 'user_id': 'bloop' }); + + } + + async main() { + + // Do capability detection here and report in a simple way if things we need don't exist with guidance on how to resolve it. + + let urlParams = (new URL(window.location.href)).searchParams; + if (urlParams.has('log')) { + this.showInfo(); + } + + this.isHeadless = /\bHeadlessChrome\//.test(navigator.userAgent); + this.isBootstrapPeer = urlParams.has("bootstrap"); + if (this.isBootstrapPeer) { + log(`This is a bootstrap peer`); + } + + this.peerID = this.getPeerID(); + this.peername = this.getPeername(); + this.userID = this.getUserID(); + this.username = this.getUsername(); + + this.peerManager = new PeerManager(this.userID, this.peerID, this.isBootstrapPeer); + this.testPeerManager(); + + // let peer: RTCPeerConnection | null = null; + // // if (window.RTCPeerConnection) { + // peer = new RTCPeerConnection({ + // iceServers: [ + // { urls: "stun:ddln.app" }, + // // { urls: "turn:ddln.app", username: "a", credential: "b" }, + // { urls: "stun:stun.l.google.com" }, // keeping this for now as my STUN server is not return ipv6 + // // { urls: "stun:stun1.l.google.com" }, + // // { urls: "stun:stun2.l.google.com" }, + // // { urls: "stun:stun3.l.google.com" }, + // // { urls: "stun:stun4.l.google.com" }, + // ] + // }); + + // peer.createDataChannel('boop'); + + // peer.onicecandidate = ({ candidate }) => { log(`WRTC:${candidate?.address} ${candidate?.protocol} ${candidate?.type} ${(candidate as any)?.url}`) }; + // peer.onnegotiationneeded = async (event) => { + // log("on negotiation needed fired"); + + // let makingOffer = false; + + // try { + // makingOffer = true; + // await peer.setLocalDescription(); + + // let IDsToSync = this.following; + // if (this.router.route === App.Route.USER) { + // IDsToSync = new Set([this.router.userID]); + // } + + // if (!peer.localDescription) { + // return; + // } + + // // this.websocket = new wsConnection(this.userID, this.peerID, IDsToSync, peer.localDescription); + // // log(peer.localDescription.type + ":" + peer.localDescription.sdp); + // // this.initOffline(this.websocket); + + // // this.websocket?.sendWebRTCDescription(peer.localDescription); + // } catch (err) { + // console.error(err); + // } finally { + // makingOffer = false; + // } + + // } + + + + + // peer.createOffer().then((description)=>{ + // peer.setLocalDescription(description) + // log("RTC: " + description.sdp + description.type); + // }); + + // } + + // await this.exportPostsForUser('b38b623c-c3fa-4351-9cab-50233c99fa4e'); + + // Get initial state and route from URL and user agent etc + + // Set local state (userid etc) based on that. + + // Init libraries + + // Render + // Load all images async + // Start the process of figuring out what posts we need + // Download posts once all current images are loaded + + + // window.resizeTo(645, 900); + + // this.initLogo() + + + this.getRoute(); + + if (this.router.route === App.Route.CONNECT) { + console.log('connect', this.router.userID); + localStorage.setItem("dandelion_id", this.router.userID); + localStorage.removeItem("dandelion_username"); + } + + + await this.initDB(); + + this.connectURL = `${document.location.origin}/connect/${this.userID}`; + document.getElementById('connectURL')!.innerHTML = `connect`; + + + + this.isHeadless = urlParams.has('headless'); + + let limitPostsParam = urlParams.get('limitPosts'); + if (limitPostsParam) { + this.limitPosts = parseInt(limitPostsParam); + } + + let time = 0; + let delta = 0; + // let isPersisted = await navigator?.storage?.persisted(); + // if (!isPersisted) { + // debugger; + // const isPersisted = await navigator.storage.persist(); + // log(`Persisted storage granted: ${isPersisted}`); + // } + + // log(`Persisted: ${(await navigator?.storage?.persisted())?.toString()}`); + + this.initMarkdown(); + + // let main = await fetch("/main.js"); + // let code = await main.text(); + // console.log(code); + // registration.active.postMessage({type:"updateMain", code:code}); + + // this.posts = await this.loadPosts(userID) ?? []; + + // debugger; + + await this.render(); // , (postID:string)=>{this.deletePost(userID, postID)} + + if ((performance as any)?.memory) { + log(`memory used: ${((performance as any).memory.usedJSHeapSize / 1024 / 1024).toFixed(2)}Mb`) + } + + // if (navigator?.storage) { + // let storageUsed = (await navigator?.storage?.estimate())?.usage/1024/1024 + // } + + // if (urlParams.get("sw") === "true") { + let registration; + registration = await this.registerServiceWorker(); + // } + + document.getElementById('username')!.innerText = `${this.username}`; + document.getElementById('peername')!.innerText = `peername:${this.peername}`; + document.getElementById('user_id')!.innerText = `user_id:${this.userID}`; + document.getElementById('peer_id')!.innerText = `peer_id:${this.peerID}`; + + this.initButtons(this.userID, this.posts, registration); + + + + log(`username:${this.username} user:${this.userID} peername:${this.peername} peer:${this.peerID}`); + + // await this.purgeEmptyUsers(); + + + + // this.listUsers() + + + // this.createNetworkViz(); + + // const client = new WebTorrent() + + // // Sintel, a free, Creative Commons movie + // const torrentId = 'magnet:?xt=urn:btih:6091e199a8d9272a40dd9a25a621a5c355d6b0be&dn=WING+IT!+-+Blender+Open+Movie+1080p.mp4&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337'; + + // client.add(torrentId, function (torrent: any) { + // // Torrents can contain many files. Let's use the .mp4 file + // const file = torrent.files.find(function (file: any) { + // return file.name.endsWith('.mp4') + // }) + + // // Display the file by adding it to the DOM. + // // Supports video, audio, image files, and more! + // file.appendTo(document.getElementById('torrent-content')); + // }) + } + + renderWelcome(contentDiv: HTMLDivElement) { + contentDiv.innerHTML = `
+ Welcome to Dandelion v0.1!
+ Loading posts for the default feed... +
+ `; + } + + // keep a map of posts to dom nodes. + // on re-render + // posts that are not in our list that we need at add + // posts that are in our list that we need to remove + + private renderedPosts = new Map(); + + async render() { + if (this.isHeadless) { + console.log('Headless so skipping render...'); + return; + } + + performance.mark("render-start"); + this.timerStart(); + + + let existingPosts = this.posts; + + + + this.posts = []; + switch (this.router.route) { + case App.Route.HOME: + case App.Route.CONNECT: { + this.following = new Set(await this.loadFollowersFromStorage(this.userID) ?? []); + this.posts = await this.getPostsForFeed(); + // this.posts = await this.loadPostsFromStorage(this.userID) ?? []; + // let compose = document.getElementById('compose'); + // if (!compose) { + // break; + // } + // compose.style.display = "block"; + break; + } + case App.Route.USER: { + this.posts = await this.loadPostsFromStorage(this.router.userID) ?? []; + let compose = document.getElementById('compose'); + if (!compose) { + break; + } + + compose.style.display = "none"; + break; + } + case App.Route.POST: { + this.posts = await this.loadPostsFromStorage(this.router.userID, this.router.postID) ?? []; + let compose = document.getElementById('compose'); + if (!compose) { + break; + } + compose.style.display = "none"; + break; + } + default: { + console.log("Render: got a route I didn't understand. Rendering HOME:", this.router.route); + this.posts = await this.loadPostsFromStorage(this.userID) ?? []; + break; + } + } + let contentDiv = document.getElementById("content"); + if (!contentDiv) { + throw new Error(); + } + if (this.posts.length === 0) { + this.renderWelcome(contentDiv as HTMLDivElement); + return; + } + + + // let existingPostSet = new Set(existingPosts.map(post => post.post_id)); + // let incomingPostSet = new Set(this.posts.map(post => post.post_id)); + + // let addedPosts = []; + // for (let post of this.posts) { + // if (!existingPostSet.has(post.post_id)) { + // addedPosts.push(post); + // } + // } + + // let deletedPosts = []; + // for (let post of existingPosts) { + // if (!incomingPostSet.has(post.post_id)) { + // deletedPosts.push(post); + // } + // } + + // console.log("added:", addedPosts, "removed:", deletedPosts); + + const fragment = document.createDocumentFragment(); + + contentDiv.innerHTML = ""; + let count = 0; + + this.renderedPosts.clear(); + let first = true; + for (let i = this.posts.length - 1; i >= 0; i--) { + let postData = this.posts[i]; + // this.postsSet.add(postData); + // TODO return promises for all image loads and await those. + let post = this.renderPost(postData.data, first); + first = false; + // this.renderedPosts.set(postData.post_id, post); + if (post) { + fragment.appendChild(post); + count++; + } + if (count > this.limitPosts) { + break; + } + } + + + if (!contentDiv) { + throw new Error("Couldn't get content div!"); + } + + contentDiv.appendChild(fragment); + + let renderTime = this.timerDelta(); + + log(`render took: ${renderTime.toFixed(2)}ms`); + performance.mark("render-end"); + performance.measure('render-time', 'render-start', 'render-end'); + + + + // if ((performance as any)?.memory) { + // log(`memory used: ${((performance as any).memory.usedJSHeapSize / 1024 / 1024).toFixed(2)}Mb`) + // } + + } + + async deletePost(userID: string, postID: string) { + deleteData(userID, postID) + + this.render(); + } + + renderPost(post: Post, first: boolean) { + if (!(post.hasOwnProperty("text"))) { + throw new Error("Post is malformed!"); + } + let containerDiv = document.createElement("div"); + + let timestamp = `${post.post_timestamp.toLocaleTimeString()} · ${post.post_timestamp.toLocaleDateString()}`; + + let deleteButton = document.createElement('button'); deleteButton.innerText = 'delete'; + deleteButton.onclick = () => { this.deletePost(post.author_id, post.post_id) }; + + // let editButton = document.createElement('button'); editButton.innerText = 'edit'; + let shareButton = document.createElement('button'); shareButton.innerText = 'share'; + shareButton.onclick = async () => { + let shareUrl = `${document.location.origin}/user/${post.author_id}/post/${post.post_id}`; + + await navigator.clipboard.writeText(shareUrl) + }; + + let ownPost = post.author_id === this.userID; + + let markdown = post.text; + if (this.markedAvailable) { + markdown = marked.parse(post.text); + } + + // if (markdown.includes("${first ? '' : '
'} +
+ @${post.author} - + ${post.post_timestamp.toLocaleDateString()} + + ${ownPost ? `` : ''} + ${ownPost ? `` : ''} + +
+
${markdown}
+ ` + + containerDiv.innerHTML = postTemplate; + + + if (ownPost) { + containerDiv.querySelector('#deleteButton')?.appendChild(deleteButton); + // containerDiv.querySelector('#editButton')?.appendChild(editButton); + } + + + containerDiv.querySelector('#shareButton')?.appendChild(shareButton); + + + if (!("image_data" in post && post.image_data)) { + // containerDiv.appendChild(timestampDiv); + return containerDiv; + // return null; + } + + let image = document.createElement("img"); + image.title = `${(post.image_data.byteLength / 1024 / 1024).toFixed(2)}MBytes`; + // const blob = new Blob([post.image_data as ArrayBuffer], { type: 'image/png' }); + const blob = new Blob([post.image_data as ArrayBuffer]); + const url = URL.createObjectURL(blob); + image.onload = () => { + URL.revokeObjectURL(url); + }; + + image.src = url; + // image.src = image.src = "data:image/png;base64," + post.image; + image.className = "postImage"; + // image.onclick = () => { App.maximizeElement(image) }; + + containerDiv.appendChild(image); + // containerDiv.appendChild(timestampDiv); + + return containerDiv; + } + + static maximizeElement(element: HTMLImageElement) { + element.style.transform = "scale(2.0)" + } + + router = { + route: App.Route.HOME, + userID: '', + postID: '', + mediaID: '' + } + + getRoute() { + let path = document.location.pathname; + console.log(">>>>>>>>>>>>>>>>>>>>>>>>>", path); + + const regex = "(user/([a-zA-Z0-9\-]+)/?(post/([a-zA-Z0-9\-]+)?/?)?(media/([0-9]+)?)?)|(connect/([a-zA-Z0-9\-]+))"; + + const match = path.match(new RegExp(regex)); + + if (match) { + if (match[8]) { // Check for the connect route + this.router.userID = match[8]; + this.router.route = App.Route.CONNECT; + } else { + + this.router.userID = match[2]; + this.router.postID = match[4]; + this.router.mediaID = match[6]; + + if (this.router.mediaID) { + this.router.route = App.Route.MEDIA; + } else if (this.router.postID) { + this.router.route = App.Route.POST; + } else { + this.router.route = App.Route.USER; + } + } + } + + console.log(">>>>>>>>>>>>>>>>>>>>>>>>>", this.router.userID, this.router.postID, this.router.mediaID, App.Route[this.router.route]); + + // user = /user/ + // post = /user//post/ + // media = /user//post//media/ + // group = /group/ID/post/ + // hashtag = /hashtag/ -- maybe only hastags in groups + // home = / + + } + +} + +namespace App { + export enum Route { + USER, + POST, + MEDIA, + GROUP, + HOME, + CONNECT, + }; +} + + + +let app = new App(); + +window.addEventListener("load", app.main.bind(app)); diff --git a/src/sw.ts b/src/sw.ts index 6307850..b0f74b0 100644 --- a/src/sw.ts +++ b/src/sw.ts @@ -5,10 +5,12 @@ const cacheName = "dandelion_cache_v1"; const contentToCache = [ '/static/index.html', '/static/main.css', - '/static/main.js', + '/static/main2.js', '/static/lib/marked.min.js', '/static/lib/qrcode.min.js', '/static/db.js', + '/static/PeerManager.js', + '/static/IDUtils.js', '/static/favicon.ico' ]; diff --git a/src/webRTC.ts b/src/webRTC.ts deleted file mode 100644 index 96ab36c..0000000 --- a/src/webRTC.ts +++ /dev/null @@ -1,110 +0,0 @@ -class PeerManager { - connect(peerID: string) { - // Connect to the peer that has the peer id peerID - } - - disconnect(peerID: string) { - } -} - -class PeerConnection { - static config = { - iceServers: [ - { urls: "stun:stun.l.google.com" }, - { urls: "stun:stun1.l.google.com" }, - { urls: "stun:stun2.l.google.com" }, - { urls: "stun:stun3.l.google.com" }, - { urls: "stun:stun4.l.google.com" }, - ], - }; - - -} - - -const config = { - iceServers: [{ urls: "stun:stun.mystunserver.tld" }], -}; - -let polite = true; - -// const signaler = new SignalingChannel(); -const signaler: any = {} -const pc = new RTCPeerConnection(config); - - -const constraints = { audio: true, video: true }; -const selfVideo = document.querySelector("video.selfview"); -const remoteVideo = document.querySelector("video.remoteview"); - -async function start() { - try { - const stream = await navigator.mediaDevices.getUserMedia(constraints); - - for (const track of stream.getTracks()) { - pc.addTrack(track, stream); - } - // selfVideo.srcObject = stream; - } catch (err) { - console.error(err); - } -} - - -pc.ontrack = ({ track, streams }) => { - track.onunmute = () => { - // if (remoteVideo.srcObject) { - // return; - // } - // remoteVideo.srcObject = streams[0]; - }; -}; - -let makingOffer = false; - -pc.onnegotiationneeded = async () => { - try { - makingOffer = true; - await pc.setLocalDescription(); - signaler.send({ description: pc.localDescription }); - } catch (err) { - console.error(err); - } finally { - makingOffer = false; - } -}; - -pc.onicecandidate = ({ candidate }) => signaler.send({ candidate }); - -let ignoreOffer = false; - -signaler.onmessage = async ({ data: { description, candidate } }: MessageEvent) => { - try { - if (description) { - const offerCollision = - description.type === "offer" && - (makingOffer || pc.signalingState !== "stable"); - - ignoreOffer = !polite && offerCollision; - if (ignoreOffer) { - return; - } - - await pc.setRemoteDescription(description); - if (description.type === "offer") { - await pc.setLocalDescription(); - signaler.send({ description: pc.localDescription }); - } - } else if (candidate) { - try { - await pc.addIceCandidate(candidate); - } catch (err) { - if (!ignoreOffer) { - throw err; - } - } - } - } catch (err) { - console.error(err); - } -}; \ No newline at end of file diff --git a/static/index.html b/static/index.html index 8f860c3..bc83c5e 100644 --- a/static/index.html +++ b/static/index.html @@ -10,19 +10,21 @@ - + - + diff --git a/static/main.css b/static/main.css index 0cb1f2f..a74cb8d 100644 --- a/static/main.css +++ b/static/main.css @@ -98,7 +98,7 @@ hr { #log { font-family: monospace; - text-wrap: nowrap; + text-wrap: wrap; font-size: 10px; margin-bottom: 20px; width: 100%; diff --git a/static/main.js b/static/main.js index df06f63..53b4886 100644 --- a/static/main.js +++ b/static/main.js @@ -191,6 +191,69 @@ async function compressString(input) { // Convert the compressed data to a Uint8Array return new Uint8Array(compressedArray); } +// class Signaler { +// websocket: WebSocket | null = null; +// websocketPingInterval: number = 0; +// connect() { +// if (this.websocket?.readyState === WebSocket.OPEN) { +// return; +// } +// window.clearInterval(this.websocketPingInterval); +// if (this.websocket) { this.websocket.close() }; +// try { +// this.websocket = new WebSocket(`wss://${window.location.hostname}:${window.location.port}/ws`); +// } catch (error: any) { +// console.log(error.message); +// return; +// } +// this.websocket.onopen = async (event) => { +// log("ws:connected"); +// await this.sendHello(); +// // If we're running as a headless peer, send a hello message every N seconds to refresh the posts we have. +// let helloRefreshIntervalPeriod = 120; +// if (app.isHeadless) { +// console.log("wsConnection: Setting hello refresh interval to ", helloRefreshIntervalPeriod) +// this.helloRefreshInterval = window.setInterval(() => { +// console.log("wsConnection: Hello refresh.") +// if (!navigator.onLine) { +// return; +// } +// this.sendHello(); +// }, helloRefreshIntervalPeriod * 1000); +// } +// this.websocketPingInterval = window.setInterval(() => { +// if (!navigator.onLine) { +// return; +// } +// this.send({ type: "ping", peer_id: this.peerID, peer_name: app.peername, user_id: app.userID, user_name: app.username }); +// }, 10_000) +// }; +// this.websocket.onclose = (event) => { +// log("ws:disconnected"); +// // this.retry *= 2; +// log(`Retrying in ${this.retry} seconds`); +// window.setTimeout(() => { this.connect(); }, this.retry * 1000); +// }; +// this.websocket.onmessage = (event) => { +// // log('ws:<-' + event.data.slice(0, 240)); +// let data = JSON.parse(event.data); +// let { type } = data; +// let handler = this.messageHandlers.get(type); +// if (!handler) { +// console.warn(`Got a message we can't handle:`, type); +// return; +// } +// handler(data); +// }; +// this.websocket.onerror = (event) => { +// log('ws:error: ' + event); +// }; +// } +// } +// disconnect() { +// this.websocket?.close(); +// } +// } class wsConnection { constructor(userID, peerID, IDsToSync) { this.websocket = null; @@ -232,10 +295,13 @@ class wsConnection { this.messageHandlers.set('hello', this.helloResponseHandler.bind(this)); this.messageHandlers.set('pong', this.pongHandler); this.messageHandlers.set('peer_message', this.peerMessageHandler.bind(this)); + // this.peerMessageHandlers.set('get_post_ids_for_user', this.getPostIdsForUserHandler.bind(this)); this.peerMessageHandlers.set('get_post_ids_for_user_response', this.getPostIdsForUserResponseHandler.bind(this)); this.peerMessageHandlers.set('get_posts_for_user', this.getPostsForUserHandler.bind(this)); this.peerMessageHandlers.set('get_posts_for_user_response', this.getPostsForUserReponseHandler.bind(this)); + this.peerMessageHandlers.set('send_webrtc_offer', this.sendWebRTCOfferHandler.bind(this)); + this.peerMessageHandlers.set('send_webrtc_offer_response', this.getPostIdsForUserResponseHandler.bind(this)); window.addEventListener('beforeunload', () => this.disconnect()); this.connect(); } @@ -260,6 +326,8 @@ class wsConnection { } pongHandler(data) { } + async sendWebRTCOfferHandler(data) { + } async getPostIdsForUserResponseHandler(data) { // log(`getPostsForUserResponse: ${data}`) let message = data.message; @@ -765,6 +833,7 @@ class App { this.websocket?.broadcastNewPost(userID, post); this.render(); } + // What happens with multiple tabs/connections from the same peer ID? I don't think this works, we also need a session ID for each connection getPeerID() { let id = localStorage.getItem("peer_id"); if (!id) { @@ -1167,6 +1236,31 @@ class App { let db = await openDatabase(this.userID); } async main() { + let urlParams = (new URL(window.location.href)).searchParams; + if (urlParams.has('log')) { + this.showInfo(); + } + let peer = null; + // if (window.RTCPeerConnection) { + peer = new RTCPeerConnection({ + iceServers: [ + { urls: "stun:ddln.app" }, + { urls: "turn:ddln.app", username: "a", credential: "b" }, + { urls: "stun:stun.l.google.com" }, // keeping this for now as my STUN server is not return ipv6 + // { urls: "stun:stun1.l.google.com" }, + // { urls: "stun:stun2.l.google.com" }, + // { urls: "stun:stun3.l.google.com" }, + // { urls: "stun:stun4.l.google.com" }, + ] + }); + peer.createDataChannel('boop'); + peer.onicecandidate = ({ candidate }) => { log(`WRTC:${candidate?.address} ${candidate?.protocol} ${candidate?.type} ${candidate?.url}`); }; + peer.onnegotiationneeded = (event) => { console.log("on negotiation needed: ", event); }; + peer.createOffer().then((description) => { + peer.setLocalDescription(description); + log("RTC: " + description.sdp + description.type); + }); + // } // await this.exportPostsForUser('b38b623c-c3fa-4351-9cab-50233c99fa4e'); // Get initial state and route from URL and user agent etc // Set local state (userid etc) based on that. @@ -1191,10 +1285,6 @@ class App { await this.initDB(); this.connectURL = `${document.location.origin}/connect/${this.userID}`; document.getElementById('connectURL').innerHTML = `connect`; - let urlParams = (new URL(window.location.href)).searchParams; - if (urlParams.has('log')) { - this.showInfo(); - } if (urlParams.has('headless')) { this.isHeadless = true; } diff --git a/static/main.js.map b/static/main.js.map index 7329545..6bba0f7 100644 --- a/static/main.js.map +++ b/static/main.js.map @@ -1 +1 @@ -{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/static/sw.js b/static/sw.js index 335f1d3..e14579b 100644 --- a/static/sw.js +++ b/static/sw.js @@ -5,10 +5,12 @@ const cacheName = "dandelion_cache_v1"; const contentToCache = [ '/static/index.html', '/static/main.css', - '/static/main.js', + '/static/main2.js', '/static/lib/marked.min.js', '/static/lib/qrcode.min.js', '/static/db.js', + '/static/PeerManager.js', + '/static/IDUtils.js', '/static/favicon.ico' ]; self.addEventListener("install", (e) => { diff --git a/static/sw.js.map b/static/sw.js.map index 4190338..dfa9bf8 100644 --- a/static/sw.js.map +++ b/static/sw.js.map @@ -1 +1 @@ -{"version":3,"file":"sw.js","sourceRoot":"","sources":["../src/sw.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"sw.js","sourceRoot":"","sources":["../src/sw.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/static/webRTC.js b/static/webRTC.js index 02af802..ecfa6f7 100644 --- a/static/webRTC.js +++ b/static/webRTC.js @@ -1,12 +1,66 @@ -"use strict"; -class PeerManager { +// import { wsConnection } from "./main"; +export class PeerManager { connect(peerID) { // Connect to the peer that has the peer id peerID } disconnect(peerID) { } } -class PeerConnection { +export class PeerConnection { + constructor(remotePeerID, signaler) { + this.makingOffer = false; + this.ignoreOffer = false; + this.onSignallerMessage = async ({ data: { description, candidate } }) => { + try { + if (description) { + // const offerCollision = + // description.type === "offer" && + // (this.makingOffer || this.rtcPeer.signalingState !== "stable"); + // this.ignoreOffer = !polite && offerCollision; + if (this.ignoreOffer) { + return; + } + await this.rtcPeer.setRemoteDescription(description); + if (description.type === "offer") { + await this.rtcPeer.setLocalDescription(); + this.signaler.send(JSON.stringify({ description: this.rtcPeer.localDescription })); + } + } + else if (candidate) { + try { + await this.rtcPeer.addIceCandidate(candidate); + } + catch (err) { + if (!this.ignoreOffer) { + throw err; + } + } + } + } + catch (err) { + console.error(err); + } + }; + this.id = remotePeerID; + this.rtcPeer = new RTCPeerConnection(PeerConnection.config); + this.signaler = signaler; + ; + this.rtcPeer.onnegotiationneeded = async () => { + try { + this.makingOffer = true; + await this.rtcPeer.setLocalDescription(); + signaler.send(JSON.stringify({ description: this.rtcPeer.localDescription })); + } + catch (err) { + console.error(err); + } + finally { + this.makingOffer = false; + } + }; + this.rtcPeer.onicecandidate = ({ candidate }) => signaler.send(JSON.stringify({ candidate })); + this.ignoreOffer = false; + } } PeerConnection.config = { iceServers: [ @@ -17,80 +71,75 @@ PeerConnection.config = { { urls: "stun:stun4.l.google.com" }, ], }; -const config = { - iceServers: [{ urls: "stun:stun.mystunserver.tld" }], -}; -let polite = true; +// const config = { +// iceServers: [{ urls: "stun:stun.mystunserver.tld" }], +// }; +// let polite = true; // const signaler = new SignalingChannel(); -const signaler = {}; -const pc = new RTCPeerConnection(config); -const constraints = { audio: true, video: true }; -const selfVideo = document.querySelector("video.selfview"); -const remoteVideo = document.querySelector("video.remoteview"); -async function start() { - try { - const stream = await navigator.mediaDevices.getUserMedia(constraints); - for (const track of stream.getTracks()) { - pc.addTrack(track, stream); - } - // selfVideo.srcObject = stream; - } - catch (err) { - console.error(err); - } -} -pc.ontrack = ({ track, streams }) => { - track.onunmute = () => { - // if (remoteVideo.srcObject) { - // return; - // } - // remoteVideo.srcObject = streams[0]; - }; -}; -let makingOffer = false; -pc.onnegotiationneeded = async () => { - try { - makingOffer = true; - await pc.setLocalDescription(); - signaler.send({ description: pc.localDescription }); - } - catch (err) { - console.error(err); - } - finally { - makingOffer = false; - } -}; -pc.onicecandidate = ({ candidate }) => signaler.send({ candidate }); -let ignoreOffer = false; -signaler.onmessage = async ({ data: { description, candidate } }) => { - try { - if (description) { - const offerCollision = description.type === "offer" && - (makingOffer || pc.signalingState !== "stable"); - ignoreOffer = !polite && offerCollision; - if (ignoreOffer) { - return; - } - await pc.setRemoteDescription(description); - if (description.type === "offer") { - await pc.setLocalDescription(); - signaler.send({ description: pc.localDescription }); - } - } - else if (candidate) { - try { - await pc.addIceCandidate(candidate); - } - catch (err) { - if (!ignoreOffer) { - throw err; - } - } - } - } - catch (err) { - console.error(err); - } -}; +// const signaler: any = {} +// const rtcPeer = new RTCPeerConnection(config); +// // const constraints = { audio: true, video: true }; +// const selfVideo = document.querySelector("video.selfview"); +// const remoteVideo = document.querySelector("video.remoteview"); +// async function start() { +// try { +// const stream = await navigator.mediaDevices.getUserMedia(constraints); +// for (const track of stream.getTracks()) { +// pc.addTrack(track, stream); +// } +// selfVideo.srcObject = stream; +// } catch (err) { +// console.error(err); +// } +// } +// rtcPeer.ontrack = ({ track, streams }) => { +// track.onunmute = () => { +// if (remoteVideo.srcObject) { +// return; +// } +// remoteVideo.srcObject = streams[0]; +// }; +// }; +// makingOffer = false; +// rtcPeer.onnegotiationneeded = async () => { +// try { +// // makingOffer = true; +// await rtcPeer.setLocalDescription(); +// signaler.send({ description: rtcPeer.localDescription }); +// } catch (err) { +// console.error(err); +// } finally { +// makingOffer = false; +// } +// }; +// rtcPeer.onicecandidate = ({ candidate }) => signaler.send({ candidate }); +// let ignoreOffer = false; +// signaler.onmessage = async ({ data: { description, candidate } }: MessageEvent) => { +// try { +// if (description) { +// const offerCollision = +// description.type === "offer" && +// // (makingOffer || rtcPeer.signalingState !== "stable"); +// ignoreOffer = !polite && offerCollision; +// if (ignoreOffer) { +// return; +// } +// await rtcPeer.setRemoteDescription(description); +// if (description.type === "offer") { +// await rtcPeer.setLocalDescription(); +// signaler.send({ description: rtcPeer.localDescription }); +// } +// } else if (candidate) { +// try { +// await rtcPeer.addIceCandidate(candidate); +// } catch (err) { +// if (!ignoreOffer) { +// throw err; +// } +// } +// } +// } catch (err) { +// console.error(err); +// } +// }; //# sourceMappingURL=webRTC.js.map \ No newline at end of file diff --git a/static/webRTC.js.map b/static/webRTC.js.map index af74ec8..9dece95 100644 --- a/static/webRTC.js.map +++ b/static/webRTC.js.map @@ -1 +1 @@ -{"version":3,"file":"webRTC.js","sourceRoot":"","sources":["../src/webRTC.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"webRTC.js","sourceRoot":"","sources":["../src/webRTC.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/webRTC.js b/webRTC.js index 02af802..9dec2b9 100644 --- a/webRTC.js +++ b/webRTC.js @@ -1,96 +1,83 @@ -"use strict"; -class PeerManager { - connect(peerID) { - // Connect to the peer that has the peer id peerID - } - disconnect(peerID) { +// https://web.dev/articles/webrtc-basics + +// handles JSON.stringify/parse + +class SignalingChannel { + send(message) { + console.log(message); } } -class PeerConnection { -} -PeerConnection.config = { - iceServers: [ - { urls: "stun:stun.l.google.com" }, - { urls: "stun:stun1.l.google.com" }, - { urls: "stun:stun2.l.google.com" }, - { urls: "stun:stun3.l.google.com" }, - { urls: "stun:stun4.l.google.com" }, - ], -}; -const config = { - iceServers: [{ urls: "stun:stun.mystunserver.tld" }], -}; -let polite = true; -// const signaler = new SignalingChannel(); -const signaler = {}; -const pc = new RTCPeerConnection(config); -const constraints = { audio: true, video: true }; -const selfVideo = document.querySelector("video.selfview"); -const remoteVideo = document.querySelector("video.remoteview"); -async function start() { - try { - const stream = await navigator.mediaDevices.getUserMedia(constraints); - for (const track of stream.getTracks()) { - pc.addTrack(track, stream); + + +function createPeerConnection(targetPeer) { + + const signaling = new SignalingChannel(); + + // const constraints = {audio: true, video: true}; + const configuration = { iceServers: [{ urls: 'stun:stunserver2024.stunprotocol.org' }] }; + const peerConnection = new RTCPeerConnection(configuration); + const sendChannel = peerConnection.createDataChannel('default'); + + + // Send any ice candidates to the other peer. + peerConnection.onicecandidate = ({ candidate }) => signaling.send({ candidate }); + + // Let the "negotiationneeded" event trigger offer generation. + peerConnection.onnegotiationneeded = async () => { + try { + await peerConnection.setLocalDescription(await peerConnection.createOffer()); + // Send the offer to the other peer. + signaling.send({ desc: peerConnection.localDescription }); + } catch (err) { + console.error(err); } - // selfVideo.srcObject = stream; - } - catch (err) { - console.error(err); - } -} -pc.ontrack = ({ track, streams }) => { - track.onunmute = () => { - // if (remoteVideo.srcObject) { - // return; - // } - // remoteVideo.srcObject = streams[0]; }; -}; -let makingOffer = false; -pc.onnegotiationneeded = async () => { - try { - makingOffer = true; - await pc.setLocalDescription(); - signaler.send({ description: pc.localDescription }); + + // // Once remote track media arrives, show it in remote video element. + // peerConnection.ontrack = (event) => { + // // Don't set srcObject again if it is already set. + // if (remoteView.srcObject) return; + // remoteView.srcObject = event.streams[0]; + // }; + + // Call start() to initiate. + async function start() { + // try { + // Get local stream, show it in self-view, and add it to be sent. + // const stream = + // await navigator.mediaDevices.getUserMedia(constraints); + // stream.getTracks().forEach((track) => + // peerConnection.addTrack(track, stream)); + // selfView.srcObject = stream; + // } catch (err) { + // console.error(err); + // } } - catch (err) { - console.error(err); - } - finally { - makingOffer = false; - } -}; -pc.onicecandidate = ({ candidate }) => signaler.send({ candidate }); -let ignoreOffer = false; -signaler.onmessage = async ({ data: { description, candidate } }) => { - try { - if (description) { - const offerCollision = description.type === "offer" && - (makingOffer || pc.signalingState !== "stable"); - ignoreOffer = !polite && offerCollision; - if (ignoreOffer) { - return; - } - await pc.setRemoteDescription(description); - if (description.type === "offer") { - await pc.setLocalDescription(); - signaler.send({ description: pc.localDescription }); - } - } - else if (candidate) { - try { - await pc.addIceCandidate(candidate); - } - catch (err) { - if (!ignoreOffer) { - throw err; + + signaling.onmessage = async ({ desc, candidate }) => { + try { + if (desc) { + // If you get an offer, you need to reply with an answer. + if (desc.type === 'offer') { + await peerConnection.setRemoteDescription(desc); + // const stream = + // await navigator.mediaDevices.getUserMedia(constraints); + // stream.getTracks().forEach((track) => + // peerConnection.addTrack(track, stream)); + await peerConnection.setLocalDescription(await peerConnection.createAnswer()); + signaling.send({ desc: peerConnection.localDescription }); + } else if (desc.type === 'answer') { + await peerConnection.setRemoteDescription(desc); + } else { + console.log('Unsupported SDP type.'); } + } else if (candidate) { + await peerConnection.addIceCandidate(candidate); } + } catch (err) { + console.error(err); } - } - catch (err) { - console.error(err); - } -}; -//# sourceMappingURL=webRTC.js.map \ No newline at end of file + }; + +} +