OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-social / bridge-email / lib / router.js

68 lines · javascript ref:
import { createHash } from 'crypto'

class Router {
  constructor (opts = {}) {
    this._seen = new Map()
    this._maxSeen = opts.maxSeen || 10000
    this._ttl = opts.ttl || 60000
    this._onExternalMessage = opts.onExternalMessage || null
    this._onKeetMessage = opts.onKeetMessage || null
  }

  _hash (text, author) {
    return createHash('sha256')
      .update(author || '')
      .update(text || '')
      .digest('hex')
      .slice(0, 16)
  }

  _isDuplicate (hash) {
    const now = Date.now()

    if (this._seen.size > this._maxSeen) {
      for (const [k, ts] of this._seen) {
        if (now - ts > this._ttl) this._seen.delete(k)
      }
    }

    if (this._seen.has(hash)) {
      const ts = this._seen.get(hash)
      if (now - ts < this._ttl) return true
    }

    this._seen.set(hash, now)
    return false
  }

  routeToKeet (author, text) {
    const hash = this._hash(text, author)
    if (this._isDuplicate(hash)) return false

    if (this._onKeetMessage) {
      this._onKeetMessage(author, text)
    }
    return true
  }

  routeToExternal (name, text) {
    const hash = this._hash(text, name)
    if (this._isDuplicate(hash)) return false

    if (this._onExternalMessage) {
      this._onExternalMessage(name, text)
    }
    return true
  }

  get seenCount () {
    return this._seen.size
  }

  clearSeen () {
    this._seen.clear()
  }
}

export { Router }