Skip to content

Instantly share code, notes, and snippets.

@tonyonodi
Created February 11, 2025 22:18
Show Gist options
  • Save tonyonodi/4621095ef87fee54ebffdbdd326fa3db to your computer and use it in GitHub Desktop.
Save tonyonodi/4621095ef87fee54ebffdbdd326fa3db to your computer and use it in GitHub Desktop.
import fs from "fs";
import express from "express";
import { WebSocketServer } from "ws";
import { NodeWSServerAdapter } from "@automerge/automerge-repo-network-websocket";
import { NodeFSStorageAdapter } from "@automerge/automerge-repo-storage-nodefs";
import os from "os";
import type { DocumentId, PeerId } from "@automerge/automerge-repo";
import {
isValidAutomergeUrl,
isValidDocumentId,
Repo,
} from "@automerge/automerge-repo";
const wss = new WebSocketServer({ noServer: true });
wss.on("connection", (ws, req) => {
console.log("connection", req.url);
ws.on("message", (message) => {});
});
const dir = "automerge-sync-server-data";
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
var hostname = os.hostname();
const PORT = process.env.PORT !== undefined ? parseInt(process.env.PORT) : 3030;
const app = express();
app.use(express.static("public"));
const db = new Map<DocumentId, PeerId>();
const network = new NodeWSServerAdapter(wss);
// Add document to db if it's not already there.
network.addListener("message", ({ documentId, senderId }) => {
if (!isValidDocumentId(documentId as DocumentId)) return;
if (db.has(documentId as DocumentId)) return;
db.set(documentId as DocumentId, senderId as PeerId);
});
const serverRepo = new Repo({
network: [network],
storage: new NodeFSStorageAdapter(dir),
peerId: `storage-server-${hostname}` as PeerId,
// Decides whethe a peer should get documents they haven't asked for.
// If they do ask for a document they get it regardless.
sharePolicy: async (peerId: PeerId, docId: DocumentId | undefined) => {
// I've no idea under what circumstances docId is undefined. Just return true for now.
// TODO: work out what to do here.
if (!docId) {
return true;
}
const isDocOwner = db.has(docId) && db.get(docId) === peerId;
return isDocOwner;
},
});
app.get("/", (req, res) => {
res.send(`👍 @automerge/example-sync-server is running`);
});
const server = app.listen(PORT, () => {
console.log(`Listening on port ${PORT}`);
});
server.on("upgrade", (request, socket, head) => {
wss.handleUpgrade(request, socket, head, (socket) => {
wss.emit("connection", socket, request);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment