OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-social / hyper-daemon / lib / runtime.js

96 lines · javascript ref:
import { TriggerEngine } from './triggers.js'
import { ActionRunner } from './actions.js'
import { DaemonStore } from './store.js'

class DaemonRuntime {
  constructor (storage, opts = {}) {
    this._storage = storage
    this._triggers = new TriggerEngine()
    this._actions = new ActionRunner({
      keetHost: opts.keetHost || 'localhost',
      keetPort: opts.keetPort || 3117,
      onLog: opts.onLog || console.log
    })
    this._store = new DaemonStore(storage)
    this._ready = false
    this._onLog = opts.onLog || console.log
  }

  async ready () {
    if (this._ready) return
    await this._store.ready()
    this._ready = true
  }

  async load (id, script) {
    await this.ready()

    // Register trigger
    this._triggers.register(id, {
      type: script.trigger.type,
      filter: script.trigger.filter || {},
      enabled: script.enabled ?? true,
      action: async (data) => {
        const results = []
        for (const action of script.actions) {
          const result = await this._actions.run(action, data)
          results.push(result)
        }

        // Log execution
        await this._store.logEvent(id, {
          timestamp: Date.now(),
          trigger: script.trigger.type,
          results
        })

        return results
      }
    })

    // Save to persistent store
    await this._store.saveScript(id, script)

    this._onLog(`[daemon] Loaded script: ${id}`)
  }

  async unload (id) {
    this._triggers.unregister(id)
    await this._store.deleteScript(id)
    this._onLog(`[daemon] Unloaded script: ${id}`)
  }

  async loadAll () {
    await this.ready()
    const scripts = await this._store.listScripts()
    for (const script of scripts) {
      await this.load(script.id, script)
    }
    return scripts.length
  }

  enable (id) { this._triggers.enable(id) }
  disable (id) { this._triggers.disable(id) }

  // Fire an event through the trigger engine
  async fire (eventType, data) {
    return this._triggers.fire(eventType, data)
  }

  list () {
    return this._triggers.list()
  }

  async getLog (id, limit = 20) {
    return this._store.getLog(id, limit)
  }

  async close () {
    this._triggers.destroy()
    await this._store.close()
    this._ready = false
  }
}

export { DaemonRuntime }