OverviewFilesCommitsIssuesDocsReleasesPeers

pgh-hello / index.js

93 lines · javascript ref:
#!/usr/bin/env node
/**
 * pgh-hello — minimal test app for the pgh OTA demo.
 *
 * Prints its version and sleeps. If PghRuntime has access to a
 * fetcher + store (typically supplied by the pgh install machinery
 * via env vars), it polls for updates in the background and logs
 * when a new tree is materialized.
 */

import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'

const HERE = path.dirname(fileURLToPath(import.meta.url))
const pkg = JSON.parse(fs.readFileSync(path.join(HERE, 'package.json'), 'utf8'))

console.log('pgh-hello v' + pkg.version)
console.log('  pid:  ' + process.pid)
console.log('  path: ' + HERE)

if (pkg.pgh && pkg.pgh.upgrade) {
  console.log('  upgrade source: ' + pkg.pgh.upgrade)
}

// Optional: wire up OTA via pgh-runtime if environment provides the
// necessary handles. Environment contract:
//   PGH_CURRENT_TREE_HASH  — tree hash pgh-hello was installed at
//   PGH_STORE_ROOT         — path to the pgh tree store
//   PGH_TOPIC              — 32-byte hex Hyperswarm topic to join
//
// This is an OPT-IN integration; if any env var is missing, pgh-hello
// just sleeps.

async function startOTA () {
  const topic = process.env.PGH_TOPIC
  const currentTreeHash = process.env.PGH_CURRENT_TREE_HASH
  const storeRoot = process.env.PGH_STORE_ROOT

  if (!topic || !currentTreeHash || !storeRoot) {
    console.log('  OTA: disabled (missing PGH_TOPIC / PGH_CURRENT_TREE_HASH / PGH_STORE_ROOT)')
    return null
  }

  try {
    const { PghRuntime } = await import('pgh-runtime')
    const { TreeStore } = await import('pgh/store')
    const { NetworkFetcher } = await import('pgh/network-fetcher')

    const store = new TreeStore({ root: storeRoot })
    store.init()

    const fetcher = new NetworkFetcher({ topic, timeout: 15000 })
    await fetcher.ready()

    const runtime = new PghRuntime({
      name: pkg.name,
      currentTreeHash,
      fetcher,
      store,
      interval: 15 * 1000, // 15s for demo
      startImmediately: true
    })

    runtime.on('updating', (release) => {
      console.log('  OTA updating → ' + release.version + ' (tree ' + release.treeHash.slice(0, 12) + ')')
    })
    runtime.on('updated', (info) => {
      console.log('  OTA updated — tree ready at ' + info.newTreeHash.slice(0, 12))
      console.log('  restart pgh-hello to apply (or pgh app rollback to revert)')
    })
    runtime.on('error', (err) => {
      console.error('  OTA error: ' + (err.message || err))
    })

    await runtime.start()
    console.log('  OTA: enabled, polling ' + topic.slice(0, 12) + '... every 15s')
    return runtime
  } catch (err) {
    console.error('  OTA: failed to start — ' + err.message)
    return null
  }
}

startOTA().then(() => {
  // Sleep forever
  setInterval(() => {}, 1 << 30)
})

process.on('SIGINT', () => { console.log('\npgh-hello shutting down'); process.exit(0) })
process.on('SIGTERM', () => { process.exit(0) })
console.log('[pgh-hello] updated by transport-test ' + new Date().toISOString())