diff --git a/src/cli.js b/src/cli.js index c17ce95..44c551d 100755 --- a/src/cli.js +++ b/src/cli.js @@ -4,6 +4,13 @@ import createSwarmHTTP from "./index.js"; const swarmHTTP = createSwarmHTTP(); function cli(command, ...args) { + process.stdout.write("> ") + process.stdin.on("data", data=> { + const input = data.toString(); + swarmHTTP.join(input); + process.stdout.write(">") + }) + const actions = { [undefined]: () => swarmHTTP.client(), server: () => swarmHTTP.server(args[0] || "."), diff --git a/src/client.js b/src/client.js index a78196e..466f092 100644 --- a/src/client.js +++ b/src/client.js @@ -6,10 +6,20 @@ const peerLink = ({ host, port }) => `http://${host}:${port}`; export default (swarm) => () => { const peers = new DictEmitter() - .on("add", (peer) => log("connection", peerLink(peer), peerLink(peer.interactive))) - .on("delete", (peer) => log("disconnection", peerLink(peer))); + .on("add", (peer) => + log("connection", peer&& peerLink(peer), peer && peerLink(peer.interactive)) + ) + .on("delete", (peer) => log("disconnection", peer && peerLink(peer))); - swarm.on("connection", (_, { peer }) => { + swarm.on("connection", (_, details) => { + swarm.on("data", (data) => { + console.log(data.toString()); + if (data.toString() === "close") { + socket.destroy(); + details.destroy(); + } + }); + const { peer } = details; if (peer) { createInteractiveWebdav({ inject: ``, diff --git a/src/index.js b/src/index.js index 717b808..26792f5 100644 --- a/src/index.js +++ b/src/index.js @@ -3,12 +3,15 @@ import crypto from "crypto"; import limited from "./utils/create-swarm.js"; -export default () => { +const hash = (data) => crypto.createHash("sha256").update(data).digest(); + +export default (defaultTopic = crypto.randomBytes(20).toString("hex")) => { const swarm = limited(hyperswarm()); - const topic = crypto.createHash("sha256").update("the-commoners").digest(); - swarm.join(topic, { lookup: true, announce: true }); + swarm.join(hash(defaultTopic), { lookup: true, announce: true }); return { + join: (topic) => swarm.join(hash(topic), { lookup: true, announce: true }), + leave: (topic) => swarm.leave(hash(topic)), client: (...args) => import("./client.js").then(({ default: f }) => f(swarm)(...args)), server: (...args) => diff --git a/src/utils/create-swarm.js b/src/utils/create-swarm.js index 4c37f50..ba90bac 100644 --- a/src/utils/create-swarm.js +++ b/src/utils/create-swarm.js @@ -1,18 +1,41 @@ +const getId = (socket) => `${socket.localAddress}:${socket.localPort}`; + export default (swarm) => { const callbacks = { connection: [], disconnection: [] }; const connections = {}; swarm.on("connection", (socket, details) => { - connections[socket.id] = { socket, details }; + connections[getId(socket)] = { socket, details }; callbacks.connection.forEach((callback) => callback(socket, details)); }); swarm.on("disconnection", (socket, details) => { - delete connections[socket.id]; + delete connections[getId(socket)]; callbacks.disconnection.forEach((callback) => callback(socket, details)); }); + swarm.on("disconnection", (socket, details) => { + socket.destroy(); + details.destroy(); + }); + let topic = null; + const gconnections = () => Object.freeze({ ...connections }); + const leave = (oldTopic, fn) => { + Object.values(gconnections()).forEach(({ socket, details }) => { + socket.destroy(); + details.destroy(); + }); + topic = null; + swarm.leave(oldTopic, fn); + }; + const join = (newTopic, options) => { + if (topic) leave(topic); + topic = newTopic; + swarm.join(topic, options); + }; + return { - join: (...args) => swarm.join(...args), - connections: Object.freeze({ ...connections }), + leave, + join, + connections: () => Object.freeze({ ...connections }), on: (event, callback) => { callbacks[event] = [...(callbacks[event] || []), callback]; if (event === "connection") {