import Corestore from 'corestore'
import Hyperswarm from 'hyperswarm'
import { WikiStore } from './wiki-store.js'
import { SearchIndex } from './search.js'
class Wiki {
constructor (storage, opts = {}) {
this._storage = storage
this._key = opts.key || null
this._store = null
this._wiki = null
this._search = null
this._swarm = null
this._ready = false
this._replicate = opts.replicate ?? false
}
async ready () {
if (this._ready) return
// Single shared Corestore for all components
this._store = new Corestore(this._storage)
this._wiki = new WikiStore(this._store, { key: this._key })
await this._wiki.ready()
this._search = new SearchIndex(this._store)
await this._search.ready()
if (this._replicate) {
this._swarm = new Hyperswarm()
this._swarm.on('connection', (conn) => {
this._store.replicate(conn)
})
const topic = this._wiki.discoveryKey
if (topic) {
this._swarm.join(topic, { server: true, client: true })
}
}
this._ready = true
}
get key () {
return this._wiki?.key || null
}
async create (slug, content, meta = {}) {
await this.ready()
const result = await this._wiki.put(slug, content, meta)
await this._search.index(slug, content, { ...meta, ...result })
return result
}
async read (slug) {
await this.ready()
return this._wiki.get(slug)
}
async update (slug, content, meta = {}) {
return this.create(slug, content, meta)
}
async remove (slug) {
await this.ready()
await this._wiki.del(slug)
await this._search.remove(slug)
}
async exists (slug) {
await this.ready()
return this._wiki.exists(slug)
}
async list () {
await this.ready()
return this._wiki.list()
}
async search (query, limit = 20) {
await this.ready()
return this._search.search(query, limit)
}
async close () {
if (this._swarm) {
await this._swarm.destroy()
}
await this._wiki.close()
if (this._store) await this._store.close()
this._ready = false
}
}
export { Wiki }