const creatures = [ ] const outputHeaderElm = document.getElementById("output-header") const outputElm = document.getElementById("output") const statusElm = document.getElementById("status") const dbnameField = document.getElementById("dbname") const dbAddressField = document.getElementById("dbaddress") const createButton = document.getElementById("create") const openButton = document.getElementById("open") const createType = document.getElementById("type") const writerText = document.getElementById("writerText") const publicCheckbox = document.getElementById("public") const readonlyCheckbox = document.getElementById("readonly") function handleError(e) { console.error(e.stack) statusElm.innerHTML = e.message } const main = async (IPFS, ORBITDB) => { let orbitdb, db let count = 0 let interval = Math.floor((Math.random() * 300) + (Math.random() * 2000)) let updateInterval let dbType, dbAddress // If we're building with Webpack, use the injected IPFS module. // Otherwise use 'Ipfs' which is exposed by ipfs.min.js if (IPFS) Ipfs = IPFS // If we're building with Webpack, use the injected OrbitDB module. // Otherwise use 'OrbitDB' which is exposed by orbitdb.min.js if (ORBITDB) OrbitDB = ORBITDB // Init UI openButton.disabled = true createButton.disabled = true statusElm.innerHTML = "Starting IPFS..." // Create IPFS instance const ipfs = await Ipfs.create({ repo: '/orbitdb/examples/browser/new/ipfs/0.33.1', start: true, preload: { enabled: false }, EXPERIMENTAL: { pubsub: true, }, config: { Addresses: { Swarm: [ // Use IPFS dev signal server // '/dns4/star-signal.cloud.ipfs.team/wss/p2p-webrtc-star', // '/dns4/ws-star.discovery.libp2p.io/tcp/443/wss/p2p-websocket-star', // Use IPFS dev webrtc signal server '/dns4/wrtc-star1.par.dwebops.pub/tcp/443/wss/p2p-webrtc-star/', '/dns4/wrtc-star2.sjc.dwebops.pub/tcp/443/wss/p2p-webrtc-star/', '/dns4/webrtc-star.discovery.libp2p.io/tcp/443/wss/p2p-webrtc-star/', // Use local signal server // '/ip4/0.0.0.0/tcp/9090/wss/p2p-webrtc-star', ] }, } }) openButton.disabled = false createButton.disabled = false statusElm.innerHTML = "IPFS Started" orbitdb = await OrbitDB.createInstance(ipfs) const load = async (db, statusText) => { // Set the status text statusElm.innerHTML = statusText // When the database is ready (ie. loaded), display results db.events.on('ready', () => queryAndRender(db)) // When database gets replicated with a peer, display results db.events.on('replicated', () => queryAndRender(db)) // When we update the database, display result db.events.on('write', () => queryAndRender(db)) db.events.on('replicate.progress', () => queryAndRender(db)) // Hook up to the load progress event and render the progress let maxTotal = 0, loaded = 0 db.events.on('load.progress', (address, hash, entry, progress, total) => { loaded ++ maxTotal = Math.max.apply(null, [maxTotal, progress, 0]) total = Math.max.apply(null, [progress, maxTotal, total, entry.clock.time, 0]) statusElm.innerHTML = `Loading database... ${maxTotal} / ${total}` }) db.events.on('ready', () => { // Set the status text setTimeout(() => { statusElm.innerHTML = 'Database is ready' }, 1000) }) // Load locally persisted database await db.load() } const startWriter = async (db, interval) => { // Set the status text writerText.innerHTML = `Writing to database every ${interval} milliseconds...` // Start update/insert loop updateInterval = setInterval(async () => { try { await update(db) } catch (e) { console.error(e.toString()) writerText.innerHTML = '' + e.toString() + '' clearInterval(updateInterval) } }, interval) } const resetDatabase = async (db) => { writerText.innerHTML = "" outputElm.innerHTML = "" outputHeaderElm.innerHTML = "" clearInterval(updateInterval) if (db) { await db.close() } interval = Math.floor((Math.random() * 300) + (Math.random() * 2000)) } const createDatabase = async () => { await resetDatabase(db) openButton.disabled = true createButton.disabled = true try { const name = dbnameField.value const type = createType.value const publicAccess = publicCheckbox.checked db = await orbitdb.open(name, { // If database doesn't exist, create it create: true, overwrite: true, // Load only the local version of the database, // don't load the latest from the network yet localOnly: false, type: type, // If "Public" flag is set, allow anyone to write to the database, // otherwise only the creator of the database can write accessController: { write: publicAccess ? ['*'] : [orbitdb.identity.id], } }) await load(db, 'Creating database...') startWriter(db, interval) } catch (e) { console.error(e) } openButton.disabled = false createButton.disabled = false } const openDatabase = async () => { const address = dbAddressField.value await resetDatabase(db) openButton.disabled = true createButton.disabled = true try { statusElm.innerHTML = "Connecting to peers..." db = await orbitdb.open(address, { sync: true }) await load(db, 'Loading database...') if (!readonlyCheckbox.checked) { startWriter(db, interval) } else { writerText.innerHTML = `Listening for updates to the database...` } } catch (e) { console.error(e) } openButton.disabled = false createButton.disabled = false } const update = async (db) => { count ++ const time = new Date().toISOString() const idx = Math.floor(Math.random() * creatures.length) const creature = creatures[idx] if (db.type === 'eventlog') { const value = "GrEEtinGs from " + orbitdb.id + " " + creature + ": Hello #" + count + " (" + time + ")" await db.add(value) } else if (db.type === 'feed') { const value = "GrEEtinGs from " + orbitdb.id + " " + creature + ": Hello #" + count + " (" + time + ")" await db.add(value) } else if (db.type === 'docstore') { const value = { _id: 'peer1', avatar: creature, updated: time } await db.put(value) } else if (db.type === 'keyvalue') { await db.set('mykey', creature) } else if (db.type === 'counter') { await db.inc(1) } else { throw new Error("Unknown datatbase type: ", db.type) } } const query = (db) => { if (db.type === 'eventlog') return db.iterator({ limit: 5 }).collect() else if (db.type === 'feed') return db.iterator({ limit: 5 }).collect() else if (db.type === 'docstore') return db.get('peer1') else if (db.type === 'keyvalue') return db.get('mykey') else if (db.type === 'counter') return db.value else throw new Error("Unknown datatbase type: ", db.type) } const queryAndRender = async (db) => { const networkPeers = await ipfs.swarm.peers() const databasePeers = await ipfs.pubsub.peers(db.address.toString()) const result = query(db) if (dbType !== db.type || dbAddress !== db.address) { dbType = db.type; dbAddress = db.address; outputHeaderElm.innerHTML = `

${dbType.toUpperCase()}

${dbAddress}

Copy this address and use the 'Open Remote Database' in another browser to replicate this database between peers.

` } outputElm.innerHTML = `
Peer ID: ${orbitdb.id}
Peers (database/network): ${databasePeers.length} / ${networkPeers.length}
Oplog Size: ${Math.max(db._replicationStatus.progress, db._oplog.length)} / ${db._replicationStatus.max}

Results

${result && Array.isArray(result) && result.length > 0 && db.type !== 'docstore' && db.type !== 'keyvalue' ? result.slice().reverse().map((e) => e.payload.value).join('
\n') : db.type === 'docstore' ? JSON.stringify(result, null, 2) : result ? result.toString().replace('"', '').replace('"', '') : result }
` } openButton.addEventListener('click', openDatabase) createButton.addEventListener('click', createDatabase) } if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') module.exports = main