prool 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,117 @@
1
+ import {
2
+ GenericContainer,
3
+ type StartedTestContainer,
4
+ Wait,
5
+ } from 'testcontainers'
6
+ import * as Instance from '../Instance.js'
7
+ import { command, type tempo as core_tempo } from '../instances/tempo.js'
8
+
9
+ export type { Instance, InstanceOptions } from '../Instance.js'
10
+
11
+ /**
12
+ * Defines a Tempo instance.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * const instance = Instance.tempo({ port: 8545 })
17
+ * await instance.start()
18
+ * // ...
19
+ * await instance.stop()
20
+ * ```
21
+ */
22
+ export const tempo = Instance.define((parameters?: tempo.Parameters) => {
23
+ const {
24
+ containerName = `tempo.${crypto.randomUUID()}`,
25
+ image = 'ghcr.io/tempoxyz/tempo:latest',
26
+ log: log_,
27
+ ...args
28
+ } = parameters || {}
29
+
30
+ const log = (() => {
31
+ try {
32
+ return JSON.parse(log_ as string)
33
+ } catch {
34
+ return log_
35
+ }
36
+ })()
37
+ const RUST_LOG = log && typeof log !== 'boolean' ? log : ''
38
+
39
+ const name = 'tempo'
40
+ let container: StartedTestContainer | undefined
41
+
42
+ return {
43
+ _internal: {
44
+ args,
45
+ },
46
+ host: args.host ?? 'localhost',
47
+ name,
48
+ port: args.port ?? 8545,
49
+ async start({ port = args.port }, { emitter }) {
50
+ const promise = Promise.withResolvers<void>()
51
+
52
+ const c = new GenericContainer(image)
53
+ .withPlatform('linux/x86_64')
54
+ .withNetworkMode('host')
55
+ .withExtraHosts([
56
+ { host: 'host.docker.internal', ipAddress: 'host-gateway' },
57
+ { host: 'localhost', ipAddress: 'host-gateway' },
58
+ ])
59
+ .withName(containerName)
60
+ .withEnvironment({ RUST_LOG })
61
+ .withCommand(command({ ...args, port }))
62
+ .withWaitStrategy(Wait.forLogMessage(/RPC HTTP server started/))
63
+ .withLogConsumer((stream) => {
64
+ stream.on('data', (data) => {
65
+ const message = data.toString()
66
+ emitter.emit('message', message)
67
+ emitter.emit('stdout', message)
68
+ if (log) console.log(message)
69
+ if (message.includes('shutting down'))
70
+ promise.reject(new Error(`Failed to start: ${message}`))
71
+ })
72
+ stream.on('error', (error) => {
73
+ if (log) console.error(error.message)
74
+ emitter.emit('message', error.message)
75
+ emitter.emit('stderr', error.message)
76
+ promise.reject(new Error(`Failed to start: ${error.message}`))
77
+ })
78
+ })
79
+ .withStartupTimeout(10_000)
80
+
81
+ c.start()
82
+ .then((c) => {
83
+ container = c
84
+ promise.resolve()
85
+ })
86
+ .catch(promise.reject)
87
+
88
+ return promise.promise
89
+ },
90
+ async stop() {
91
+ if (!container) return
92
+ await container.stop()
93
+ container = undefined
94
+ },
95
+ }
96
+ })
97
+
98
+ export declare namespace tempo {
99
+ export type Parameters = Omit<core_tempo.Parameters, 'binary'> & {
100
+ /**
101
+ * Name of the container.
102
+ */
103
+ containerName?: string | undefined
104
+ /**
105
+ * Docker image to use.
106
+ */
107
+ image?: string | undefined
108
+ /**
109
+ * Host the server will listen on.
110
+ */
111
+ host?: string | undefined
112
+ /**
113
+ * Port the server will listen on.
114
+ */
115
+ port?: number | undefined
116
+ }
117
+ }
@@ -0,0 +1 @@
1
+ export * as Instance from './Instance.js'