• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

cameri / nostream / 24611665835

18 Apr 2026 07:00PM UTC coverage: 68.349% (+2.5%) from 65.886%
24611665835

Pull #499

github

web-flow
Merge 80664cf62 into b73bcdcc5
Pull Request #499: feat: i2p support addition (#35)

929 of 1469 branches covered (63.24%)

Branch coverage included in aggregate %.

2416 of 3425 relevant lines covered (70.54%)

11.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/scripts/export-events.ts
1
import 'pg-query-stream'
×
2

3
import fs from 'fs'
×
4
import path from 'path'
×
5
import { pipeline } from 'stream/promises'
×
6
import { Transform } from 'stream'
×
7

8
import { getMasterDbClient } from '../database/client'
×
9

10
type EventRow = {
11
  event_id: Buffer
12
  event_pubkey: Buffer
13
  event_kind: number
14
  event_created_at: number
15
  event_content: string
16
  event_tags: unknown[] | null
17
  event_signature: Buffer
18
}
19

20
async function exportEvents(): Promise<void> {
21
  const filename = process.argv[2] || 'events.jsonl'
×
22
  const outputPath = path.resolve(filename)
×
23
  const db = getMasterDbClient()
×
24
  const abortController = new AbortController()
×
25
  let interruptedBySignal: NodeJS.Signals | undefined
26

27
  const onSignal = (signal: NodeJS.Signals) => {
×
28
    if (abortController.signal.aborted) {
×
29
      return
×
30
    }
31

32
    interruptedBySignal = signal
×
33
    process.exitCode = 130
×
34
    console.log(`${signal} received. Stopping export...`)
×
35
    abortController.abort()
×
36
  }
37

38
  process.on('SIGINT', onSignal).on('SIGTERM', onSignal)
×
39

40
  try {
×
41
    const firstEvent = await db('events').select('event_id').whereNull('deleted_at').first()
×
42

43
    if (abortController.signal.aborted) {
×
44
      return
×
45
    }
46

47
    if (!firstEvent) {
×
48
      console.log('No events to export.')
×
49
      return
×
50
    }
51

52
    console.log(`Exporting events to ${outputPath}`)
×
53

54
    const output = fs.createWriteStream(outputPath)
×
55
    let exported = 0
×
56

57
    const dbStream = db('events')
×
58
      .select(
59
        'event_id',
60
        'event_pubkey',
61
        'event_kind',
62
        'event_created_at',
63
        'event_content',
64
        'event_tags',
65
        'event_signature',
66
      )
67
      .whereNull('deleted_at')
68
      .orderBy('event_created_at', 'asc')
69
      .orderBy('event_id', 'asc')
70
      .stream()
71

72
    const toJsonLine = new Transform({
×
73
      objectMode: true,
74
      transform(row: EventRow, _encoding, callback) {
75
        const event = {
×
76
          id: row.event_id.toString('hex'),
77
          pubkey: row.event_pubkey.toString('hex'),
78
          created_at: row.event_created_at,
79
          kind: row.event_kind,
80
          tags: Array.isArray(row.event_tags) ? row.event_tags : [],
×
81
          content: row.event_content,
82
          sig: row.event_signature.toString('hex'),
83
        }
84

85
        exported++
×
86
        if (exported % 10000 === 0) {
×
87
          console.log(`Exported ${exported} events...`)
×
88
        }
89

90
        callback(null, JSON.stringify(event) + '\n')
×
91
      },
92
    })
93

94
    await pipeline(dbStream, toJsonLine, output, {
×
95
      signal: abortController.signal,
96
    })
97

98
    console.log(`Export complete: ${exported} events written to ${outputPath}`)
×
99
  } catch (error) {
100
    if (abortController.signal.aborted) {
×
101
      console.log(`Export interrupted by ${interruptedBySignal ?? 'signal'}.`)
×
102
      process.exitCode = 130
×
103
      return
×
104
    }
105

106
    throw error
×
107
  } finally {
108
    process.off('SIGINT', onSignal).off('SIGTERM', onSignal)
×
109

110
    await db.destroy()
×
111
  }
112
}
113

114
exportEvents().catch((error) => {
×
115
  console.error('Export failed:', error.message)
×
116
  process.exit(1)
×
117
})
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc