@no-witness-labs/midday-sdk 0.1.2 → 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.
- package/dist/devnet/Cluster.d.ts +282 -0
- package/dist/devnet/Cluster.d.ts.map +1 -0
- package/dist/devnet/Cluster.js +487 -0
- package/dist/devnet/Cluster.js.map +1 -0
- package/dist/devnet/Config.d.ts +119 -0
- package/dist/devnet/Config.d.ts.map +1 -0
- package/dist/devnet/Config.js +75 -0
- package/dist/devnet/Config.js.map +1 -0
- package/dist/devnet/Container.d.ts +180 -0
- package/dist/devnet/Container.d.ts.map +1 -0
- package/dist/devnet/Container.js +390 -0
- package/dist/devnet/Container.js.map +1 -0
- package/dist/devnet/Health.d.ts +129 -0
- package/dist/devnet/Health.d.ts.map +1 -0
- package/dist/devnet/Health.js +304 -0
- package/dist/devnet/Health.js.map +1 -0
- package/dist/devnet/Images.d.ts +43 -0
- package/dist/devnet/Images.d.ts.map +1 -0
- package/dist/devnet/Images.js +96 -0
- package/dist/devnet/Images.js.map +1 -0
- package/dist/devnet/errors.d.ts +65 -0
- package/dist/devnet/errors.d.ts.map +1 -0
- package/dist/devnet/errors.js +40 -0
- package/dist/devnet/errors.js.map +1 -0
- package/dist/devnet/index.d.ts +72 -0
- package/dist/devnet/index.d.ts.map +1 -0
- package/dist/devnet/index.js +73 -0
- package/dist/devnet/index.js.map +1 -0
- package/package.json +14 -4
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Health check utilities for DevNet containers.
|
|
3
|
+
*
|
|
4
|
+
* ## API Design
|
|
5
|
+
*
|
|
6
|
+
* This module uses a **module-function pattern**:
|
|
7
|
+
*
|
|
8
|
+
* - **Stateless**: Health checks are pure functions
|
|
9
|
+
* - **Module functions**: `Health.waitForNode(port)`, `Health.waitForIndexer(port)`
|
|
10
|
+
* - **No instance needed**: Just utility functions
|
|
11
|
+
*
|
|
12
|
+
* ### Usage Patterns
|
|
13
|
+
*
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // Promise user
|
|
16
|
+
* await Health.waitForNode(9944);
|
|
17
|
+
* await Health.waitForIndexer(8088);
|
|
18
|
+
*
|
|
19
|
+
* // Effect user
|
|
20
|
+
* yield* Health.effect.waitForNode(9944);
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @since 0.2.0
|
|
24
|
+
* @module
|
|
25
|
+
*/
|
|
26
|
+
import { Context, Effect, Layer } from 'effect';
|
|
27
|
+
import { HealthCheckError } from './errors.js';
|
|
28
|
+
/**
|
|
29
|
+
* Options for health check polling.
|
|
30
|
+
*
|
|
31
|
+
* @since 0.2.0
|
|
32
|
+
* @category model
|
|
33
|
+
*/
|
|
34
|
+
export interface HealthCheckOptions {
|
|
35
|
+
/** Maximum time to wait in milliseconds (default: 60000) */
|
|
36
|
+
timeout?: number;
|
|
37
|
+
/** Interval between checks in milliseconds (default: 1000) */
|
|
38
|
+
interval?: number;
|
|
39
|
+
/** Number of consecutive successes required (default: 1) */
|
|
40
|
+
requiredSuccesses?: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Service interface for Health check operations.
|
|
44
|
+
*
|
|
45
|
+
* Use with Effect's dependency injection system.
|
|
46
|
+
*
|
|
47
|
+
* @since 0.2.0
|
|
48
|
+
* @category service
|
|
49
|
+
*/
|
|
50
|
+
export interface HealthServiceImpl {
|
|
51
|
+
readonly waitForHttp: (url: string, options?: HealthCheckOptions) => Effect.Effect<void, HealthCheckError>;
|
|
52
|
+
readonly waitForWebSocket: (url: string, options?: HealthCheckOptions) => Effect.Effect<void, HealthCheckError>;
|
|
53
|
+
readonly waitForNode: (port: number, options?: HealthCheckOptions) => Effect.Effect<void, HealthCheckError>;
|
|
54
|
+
readonly waitForIndexer: (port: number, options?: HealthCheckOptions) => Effect.Effect<void, HealthCheckError>;
|
|
55
|
+
readonly waitForProofServer: (port: number, options?: HealthCheckOptions) => Effect.Effect<void, HealthCheckError>;
|
|
56
|
+
}
|
|
57
|
+
declare const HealthService_base: Context.TagClass<HealthService, "HealthService", HealthServiceImpl>;
|
|
58
|
+
/**
|
|
59
|
+
* Context.Tag for HealthService dependency injection.
|
|
60
|
+
*
|
|
61
|
+
* @since 0.2.0
|
|
62
|
+
* @category service
|
|
63
|
+
*/
|
|
64
|
+
export declare class HealthService extends HealthService_base {
|
|
65
|
+
}
|
|
66
|
+
declare function waitForHttpEffect(url: string, options?: HealthCheckOptions): Effect.Effect<void, HealthCheckError>;
|
|
67
|
+
/**
|
|
68
|
+
* Wait for an HTTP endpoint to return a successful response.
|
|
69
|
+
*
|
|
70
|
+
* @since 0.2.0
|
|
71
|
+
* @category health
|
|
72
|
+
*/
|
|
73
|
+
export declare function waitForHttp(url: string, options?: HealthCheckOptions): Promise<void>;
|
|
74
|
+
declare function waitForWebSocketEffect(url: string, options?: HealthCheckOptions): Effect.Effect<void, HealthCheckError>;
|
|
75
|
+
/**
|
|
76
|
+
* Wait for a WebSocket endpoint to accept connections.
|
|
77
|
+
*
|
|
78
|
+
* @since 0.2.0
|
|
79
|
+
* @category health
|
|
80
|
+
*/
|
|
81
|
+
export declare function waitForWebSocket(url: string, options?: HealthCheckOptions): Promise<void>;
|
|
82
|
+
declare function waitForNodeEffect(port: number, options?: HealthCheckOptions): Effect.Effect<void, HealthCheckError>;
|
|
83
|
+
/**
|
|
84
|
+
* Wait for the Midnight node to be ready.
|
|
85
|
+
*
|
|
86
|
+
* @since 0.2.0
|
|
87
|
+
* @category health
|
|
88
|
+
*/
|
|
89
|
+
export declare function waitForNode(port: number, options?: HealthCheckOptions): Promise<void>;
|
|
90
|
+
declare function waitForIndexerEffect(port: number, options?: HealthCheckOptions): Effect.Effect<void, HealthCheckError>;
|
|
91
|
+
/**
|
|
92
|
+
* Wait for the indexer to be ready.
|
|
93
|
+
*
|
|
94
|
+
* @since 0.2.0
|
|
95
|
+
* @category health
|
|
96
|
+
*/
|
|
97
|
+
export declare function waitForIndexer(port: number, options?: HealthCheckOptions): Promise<void>;
|
|
98
|
+
declare function waitForProofServerEffect(port: number, options?: HealthCheckOptions): Effect.Effect<void, HealthCheckError>;
|
|
99
|
+
/**
|
|
100
|
+
* Wait for the proof server to be ready.
|
|
101
|
+
*
|
|
102
|
+
* @since 0.2.0
|
|
103
|
+
* @category health
|
|
104
|
+
*/
|
|
105
|
+
export declare function waitForProofServer(port: number, options?: HealthCheckOptions): Promise<void>;
|
|
106
|
+
/**
|
|
107
|
+
* Raw Effect APIs for advanced users.
|
|
108
|
+
*
|
|
109
|
+
* @since 0.2.0
|
|
110
|
+
* @category effect
|
|
111
|
+
*/
|
|
112
|
+
export declare const effect: {
|
|
113
|
+
waitForHttp: typeof waitForHttpEffect;
|
|
114
|
+
waitForWebSocket: typeof waitForWebSocketEffect;
|
|
115
|
+
waitForNode: typeof waitForNodeEffect;
|
|
116
|
+
waitForIndexer: typeof waitForIndexerEffect;
|
|
117
|
+
waitForProofServer: typeof waitForProofServerEffect;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Live Layer for HealthService.
|
|
121
|
+
*
|
|
122
|
+
* Provides the default implementation of HealthService for Effect DI.
|
|
123
|
+
*
|
|
124
|
+
* @since 0.2.0
|
|
125
|
+
* @category layer
|
|
126
|
+
*/
|
|
127
|
+
export declare const Live: Layer.Layer<HealthService>;
|
|
128
|
+
export {};
|
|
129
|
+
//# sourceMappingURL=Health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Health.d.ts","sourceRoot":"","sources":["../../src/devnet/Health.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Health check utilities for DevNet containers.
|
|
3
|
+
*
|
|
4
|
+
* ## API Design
|
|
5
|
+
*
|
|
6
|
+
* This module uses a **module-function pattern**:
|
|
7
|
+
*
|
|
8
|
+
* - **Stateless**: Health checks are pure functions
|
|
9
|
+
* - **Module functions**: `Health.waitForNode(port)`, `Health.waitForIndexer(port)`
|
|
10
|
+
* - **No instance needed**: Just utility functions
|
|
11
|
+
*
|
|
12
|
+
* ### Usage Patterns
|
|
13
|
+
*
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // Promise user
|
|
16
|
+
* await Health.waitForNode(9944);
|
|
17
|
+
* await Health.waitForIndexer(8088);
|
|
18
|
+
*
|
|
19
|
+
* // Effect user
|
|
20
|
+
* yield* Health.effect.waitForNode(9944);
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @since 0.2.0
|
|
24
|
+
* @module
|
|
25
|
+
*/
|
|
26
|
+
import { Context, Effect, Layer } from 'effect';
|
|
27
|
+
import { HealthCheckError } from './errors.js';
|
|
28
|
+
/**
|
|
29
|
+
* Context.Tag for HealthService dependency injection.
|
|
30
|
+
*
|
|
31
|
+
* @since 0.2.0
|
|
32
|
+
* @category service
|
|
33
|
+
*/
|
|
34
|
+
export class HealthService extends Context.Tag('HealthService')() {
|
|
35
|
+
}
|
|
36
|
+
// Internal Effect implementation
|
|
37
|
+
function waitForHttpEffect(url, options = {}) {
|
|
38
|
+
return Effect.gen(function* () {
|
|
39
|
+
yield* Effect.tryPromise({
|
|
40
|
+
try: async () => {
|
|
41
|
+
const { timeout = 60000, interval = 1000, requiredSuccesses = 1 } = options;
|
|
42
|
+
const startTime = Date.now();
|
|
43
|
+
let successCount = 0;
|
|
44
|
+
while (Date.now() - startTime < timeout) {
|
|
45
|
+
try {
|
|
46
|
+
const response = await fetch(url, {
|
|
47
|
+
method: 'GET',
|
|
48
|
+
signal: AbortSignal.timeout(5000),
|
|
49
|
+
});
|
|
50
|
+
if (response.ok) {
|
|
51
|
+
successCount++;
|
|
52
|
+
if (successCount >= requiredSuccesses) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
successCount = 0;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
successCount = 0;
|
|
62
|
+
}
|
|
63
|
+
await sleep(interval);
|
|
64
|
+
}
|
|
65
|
+
throw new Error(`Health check timed out after ${timeout}ms for ${url}`);
|
|
66
|
+
},
|
|
67
|
+
catch: (cause) => new HealthCheckError({
|
|
68
|
+
service: url,
|
|
69
|
+
cause,
|
|
70
|
+
}),
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Wait for an HTTP endpoint to return a successful response.
|
|
76
|
+
*
|
|
77
|
+
* @since 0.2.0
|
|
78
|
+
* @category health
|
|
79
|
+
*/
|
|
80
|
+
export async function waitForHttp(url, options = {}) {
|
|
81
|
+
return Effect.runPromise(waitForHttpEffect(url, options));
|
|
82
|
+
}
|
|
83
|
+
// Internal Effect implementation
|
|
84
|
+
function waitForWebSocketEffect(url, options = {}) {
|
|
85
|
+
return Effect.gen(function* () {
|
|
86
|
+
yield* Effect.tryPromise({
|
|
87
|
+
try: async () => {
|
|
88
|
+
const { timeout = 60000, interval = 1000, requiredSuccesses = 1 } = options;
|
|
89
|
+
const startTime = Date.now();
|
|
90
|
+
let successCount = 0;
|
|
91
|
+
while (Date.now() - startTime < timeout) {
|
|
92
|
+
try {
|
|
93
|
+
const connected = await checkWebSocketConnection(url);
|
|
94
|
+
if (connected) {
|
|
95
|
+
successCount++;
|
|
96
|
+
if (successCount >= requiredSuccesses) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
successCount = 0;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
successCount = 0;
|
|
106
|
+
}
|
|
107
|
+
await sleep(interval);
|
|
108
|
+
}
|
|
109
|
+
throw new Error(`WebSocket check timed out after ${timeout}ms for ${url}`);
|
|
110
|
+
},
|
|
111
|
+
catch: (cause) => new HealthCheckError({
|
|
112
|
+
service: url,
|
|
113
|
+
cause,
|
|
114
|
+
}),
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Wait for a WebSocket endpoint to accept connections.
|
|
120
|
+
*
|
|
121
|
+
* @since 0.2.0
|
|
122
|
+
* @category health
|
|
123
|
+
*/
|
|
124
|
+
export async function waitForWebSocket(url, options = {}) {
|
|
125
|
+
return Effect.runPromise(waitForWebSocketEffect(url, options));
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Check if a WebSocket endpoint accepts connections.
|
|
129
|
+
*/
|
|
130
|
+
async function checkWebSocketConnection(url) {
|
|
131
|
+
return new Promise((resolve) => {
|
|
132
|
+
// Use dynamic import for WebSocket to support both Node.js and browser
|
|
133
|
+
import('ws').then(({ default: WebSocket }) => {
|
|
134
|
+
const ws = new WebSocket(url);
|
|
135
|
+
const timeout = setTimeout(() => {
|
|
136
|
+
ws.close();
|
|
137
|
+
resolve(false);
|
|
138
|
+
}, 5000);
|
|
139
|
+
ws.on('open', () => {
|
|
140
|
+
clearTimeout(timeout);
|
|
141
|
+
ws.close();
|
|
142
|
+
resolve(true);
|
|
143
|
+
});
|
|
144
|
+
ws.on('error', () => {
|
|
145
|
+
clearTimeout(timeout);
|
|
146
|
+
resolve(false);
|
|
147
|
+
});
|
|
148
|
+
}).catch(() => {
|
|
149
|
+
resolve(false);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// Internal Effect implementation
|
|
154
|
+
function waitForNodeEffect(port, options = {}) {
|
|
155
|
+
const url = `http://localhost:${port}/health`;
|
|
156
|
+
return waitForHttpEffect(url, { timeout: 90000, ...options });
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Wait for the Midnight node to be ready.
|
|
160
|
+
*
|
|
161
|
+
* @since 0.2.0
|
|
162
|
+
* @category health
|
|
163
|
+
*/
|
|
164
|
+
export async function waitForNode(port, options = {}) {
|
|
165
|
+
return Effect.runPromise(waitForNodeEffect(port, options));
|
|
166
|
+
}
|
|
167
|
+
// Internal Effect implementation
|
|
168
|
+
function waitForIndexerEffect(port, options = {}) {
|
|
169
|
+
// The indexer GraphQL endpoint
|
|
170
|
+
const url = `http://localhost:${port}/api/v3/graphql`;
|
|
171
|
+
// Indexer needs more time to sync with node
|
|
172
|
+
return waitForGraphQLEffect(url, { timeout: 120000, ...options });
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Wait for the indexer to be ready.
|
|
176
|
+
*
|
|
177
|
+
* @since 0.2.0
|
|
178
|
+
* @category health
|
|
179
|
+
*/
|
|
180
|
+
export async function waitForIndexer(port, options = {}) {
|
|
181
|
+
return Effect.runPromise(waitForIndexerEffect(port, options));
|
|
182
|
+
}
|
|
183
|
+
// Internal Effect implementation for GraphQL
|
|
184
|
+
function waitForGraphQLEffect(url, options = {}) {
|
|
185
|
+
return Effect.gen(function* () {
|
|
186
|
+
yield* Effect.tryPromise({
|
|
187
|
+
try: async () => {
|
|
188
|
+
const { timeout = 60000, interval = 2000 } = options;
|
|
189
|
+
const startTime = Date.now();
|
|
190
|
+
while (Date.now() - startTime < timeout) {
|
|
191
|
+
try {
|
|
192
|
+
const response = await fetch(url, {
|
|
193
|
+
method: 'POST',
|
|
194
|
+
headers: { 'Content-Type': 'application/json' },
|
|
195
|
+
body: JSON.stringify({
|
|
196
|
+
query: '{ __typename }',
|
|
197
|
+
}),
|
|
198
|
+
signal: AbortSignal.timeout(5000),
|
|
199
|
+
});
|
|
200
|
+
if (response.ok) {
|
|
201
|
+
const data = (await response.json());
|
|
202
|
+
if (data && !data.errors) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
// Continue polling
|
|
209
|
+
}
|
|
210
|
+
await sleep(interval);
|
|
211
|
+
}
|
|
212
|
+
throw new Error(`GraphQL check timed out after ${timeout}ms for ${url}`);
|
|
213
|
+
},
|
|
214
|
+
catch: (cause) => new HealthCheckError({
|
|
215
|
+
service: url,
|
|
216
|
+
cause,
|
|
217
|
+
}),
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
// Internal Effect implementation
|
|
222
|
+
function waitForProofServerEffect(port, options = {}) {
|
|
223
|
+
// Proof server exposes gRPC, we'll check if the port is open
|
|
224
|
+
// Just check if we can connect (proof server may not have HTTP health endpoint)
|
|
225
|
+
return waitForPortEffect(port, { timeout: 60000, ...options });
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Wait for the proof server to be ready.
|
|
229
|
+
*
|
|
230
|
+
* @since 0.2.0
|
|
231
|
+
* @category health
|
|
232
|
+
*/
|
|
233
|
+
export async function waitForProofServer(port, options = {}) {
|
|
234
|
+
return Effect.runPromise(waitForProofServerEffect(port, options));
|
|
235
|
+
}
|
|
236
|
+
// Internal Effect implementation for port checking
|
|
237
|
+
function waitForPortEffect(port, options = {}) {
|
|
238
|
+
return Effect.gen(function* () {
|
|
239
|
+
yield* Effect.tryPromise({
|
|
240
|
+
try: async () => {
|
|
241
|
+
const { timeout = 60000, interval = 1000 } = options;
|
|
242
|
+
const startTime = Date.now();
|
|
243
|
+
const { createConnection } = await import('net');
|
|
244
|
+
while (Date.now() - startTime < timeout) {
|
|
245
|
+
const connected = await new Promise((resolve) => {
|
|
246
|
+
const socket = createConnection({ port, host: 'localhost' }, () => {
|
|
247
|
+
socket.destroy();
|
|
248
|
+
resolve(true);
|
|
249
|
+
});
|
|
250
|
+
socket.on('error', () => {
|
|
251
|
+
socket.destroy();
|
|
252
|
+
resolve(false);
|
|
253
|
+
});
|
|
254
|
+
socket.setTimeout(2000, () => {
|
|
255
|
+
socket.destroy();
|
|
256
|
+
resolve(false);
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
if (connected) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
await sleep(interval);
|
|
263
|
+
}
|
|
264
|
+
throw new Error(`Port check timed out after ${timeout}ms for port ${port}`);
|
|
265
|
+
},
|
|
266
|
+
catch: (cause) => new HealthCheckError({
|
|
267
|
+
service: `port ${port}`,
|
|
268
|
+
cause,
|
|
269
|
+
}),
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
function sleep(ms) {
|
|
274
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Raw Effect APIs for advanced users.
|
|
278
|
+
*
|
|
279
|
+
* @since 0.2.0
|
|
280
|
+
* @category effect
|
|
281
|
+
*/
|
|
282
|
+
export const effect = {
|
|
283
|
+
waitForHttp: waitForHttpEffect,
|
|
284
|
+
waitForWebSocket: waitForWebSocketEffect,
|
|
285
|
+
waitForNode: waitForNodeEffect,
|
|
286
|
+
waitForIndexer: waitForIndexerEffect,
|
|
287
|
+
waitForProofServer: waitForProofServerEffect,
|
|
288
|
+
};
|
|
289
|
+
/**
|
|
290
|
+
* Live Layer for HealthService.
|
|
291
|
+
*
|
|
292
|
+
* Provides the default implementation of HealthService for Effect DI.
|
|
293
|
+
*
|
|
294
|
+
* @since 0.2.0
|
|
295
|
+
* @category layer
|
|
296
|
+
*/
|
|
297
|
+
export const Live = Layer.succeed(HealthService, {
|
|
298
|
+
waitForHttp: waitForHttpEffect,
|
|
299
|
+
waitForWebSocket: waitForWebSocketEffect,
|
|
300
|
+
waitForNode: waitForNodeEffect,
|
|
301
|
+
waitForIndexer: waitForIndexerEffect,
|
|
302
|
+
waitForProofServer: waitForProofServerEffect,
|
|
303
|
+
});
|
|
304
|
+
//# sourceMappingURL=Health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Health.js","sourceRoot":"","sources":["../../src/devnet/Health.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docker image management utilities.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.2.0
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Error thrown when image operations fail.
|
|
9
|
+
*
|
|
10
|
+
* @since 0.2.0
|
|
11
|
+
* @category errors
|
|
12
|
+
*/
|
|
13
|
+
export declare class ImageError extends Error {
|
|
14
|
+
readonly reason: string;
|
|
15
|
+
readonly cause?: unknown;
|
|
16
|
+
constructor(options: {
|
|
17
|
+
reason: string;
|
|
18
|
+
message: string;
|
|
19
|
+
cause?: unknown;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Check if a Docker image exists locally.
|
|
24
|
+
*
|
|
25
|
+
* @since 0.2.0
|
|
26
|
+
* @category inspection
|
|
27
|
+
*/
|
|
28
|
+
export declare function isAvailable(imageName: string): Promise<boolean>;
|
|
29
|
+
/**
|
|
30
|
+
* Pull a Docker image with progress logging.
|
|
31
|
+
*
|
|
32
|
+
* @since 0.2.0
|
|
33
|
+
* @category management
|
|
34
|
+
*/
|
|
35
|
+
export declare function pull(imageName: string): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Ensure image is available, pull if necessary.
|
|
38
|
+
*
|
|
39
|
+
* @since 0.2.0
|
|
40
|
+
* @category management
|
|
41
|
+
*/
|
|
42
|
+
export declare function ensureAvailable(imageName: string): Promise<void>;
|
|
43
|
+
//# sourceMappingURL=Images.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Images.d.ts","sourceRoot":"","sources":["../../src/devnet/Images.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;GAKG;AACH,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,SAAkB,KAAK,CAAC,EAAE,OAAO,CAAC;gBAEtB,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAM1E;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAcrE;AAED;;;;;GAKG;AACH,wBAAsB,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwC3D;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKtE"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docker image management utilities.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.2.0
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import Docker from 'dockerode';
|
|
8
|
+
/**
|
|
9
|
+
* Error thrown when image operations fail.
|
|
10
|
+
*
|
|
11
|
+
* @since 0.2.0
|
|
12
|
+
* @category errors
|
|
13
|
+
*/
|
|
14
|
+
export class ImageError extends Error {
|
|
15
|
+
reason;
|
|
16
|
+
cause;
|
|
17
|
+
constructor(options) {
|
|
18
|
+
super(options.message);
|
|
19
|
+
this.name = 'ImageError';
|
|
20
|
+
this.reason = options.reason;
|
|
21
|
+
this.cause = options.cause;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Check if a Docker image exists locally.
|
|
26
|
+
*
|
|
27
|
+
* @since 0.2.0
|
|
28
|
+
* @category inspection
|
|
29
|
+
*/
|
|
30
|
+
export async function isAvailable(imageName) {
|
|
31
|
+
try {
|
|
32
|
+
const docker = new Docker();
|
|
33
|
+
const images = await docker.listImages({
|
|
34
|
+
filters: { reference: [imageName] },
|
|
35
|
+
});
|
|
36
|
+
return images.length > 0;
|
|
37
|
+
}
|
|
38
|
+
catch (cause) {
|
|
39
|
+
throw new ImageError({
|
|
40
|
+
reason: 'image_inspection_failed',
|
|
41
|
+
message: `Failed to check if image '${imageName}' is available.`,
|
|
42
|
+
cause,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Pull a Docker image with progress logging.
|
|
48
|
+
*
|
|
49
|
+
* @since 0.2.0
|
|
50
|
+
* @category management
|
|
51
|
+
*/
|
|
52
|
+
export async function pull(imageName) {
|
|
53
|
+
const docker = new Docker();
|
|
54
|
+
console.log(`[Devnet] Pulling Docker image: ${imageName}`);
|
|
55
|
+
console.log(`[Devnet] This may take a few minutes on first run...`);
|
|
56
|
+
let stream;
|
|
57
|
+
try {
|
|
58
|
+
stream = await docker.pull(imageName);
|
|
59
|
+
}
|
|
60
|
+
catch (cause) {
|
|
61
|
+
throw new ImageError({
|
|
62
|
+
reason: 'image_pull_failed',
|
|
63
|
+
message: `Failed to pull image '${imageName}'. Check internet connection and image name.`,
|
|
64
|
+
cause,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
// Wait for pull to complete
|
|
68
|
+
await new Promise((resolve, reject) => {
|
|
69
|
+
docker.modem.followProgress(stream, (err) => {
|
|
70
|
+
if (err)
|
|
71
|
+
reject(err);
|
|
72
|
+
else
|
|
73
|
+
resolve();
|
|
74
|
+
}, (event) => {
|
|
75
|
+
if (event.status &&
|
|
76
|
+
event.status !== 'Downloading' &&
|
|
77
|
+
event.status !== 'Extracting') {
|
|
78
|
+
console.log(`[Devnet] ${event.status}${event.id ? ` ${event.id}` : ''}`);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
console.log(`[Devnet] ✓ Image ready: ${imageName}`);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Ensure image is available, pull if necessary.
|
|
86
|
+
*
|
|
87
|
+
* @since 0.2.0
|
|
88
|
+
* @category management
|
|
89
|
+
*/
|
|
90
|
+
export async function ensureAvailable(imageName) {
|
|
91
|
+
const available = await isAvailable(imageName);
|
|
92
|
+
if (!available) {
|
|
93
|
+
await pull(imageName);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=Images.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Images.js","sourceRoot":"","sources":["../../src/devnet/Images.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,MAAM,MAAM,WAAW,CAAC;AAE/B;;;;;GAKG;AACH,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,MAAM,CAAS;IACN,KAAK,CAAW;IAElC,YAAY,OAA6D;QACvE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC7B,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,SAAiB;IACjD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC;YACrC,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,SAAS,CAAC,EAAE;SACpC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,UAAU,CAAC;YACnB,MAAM,EAAE,yBAAyB;YACjC,OAAO,EAAE,6BAA6B,SAAS,iBAAiB;YAChE,KAAK;SACN,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,SAAiB;IAC1C,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;IAE5B,OAAO,CAAC,GAAG,CAAC,kCAAkC,SAAS,EAAE,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;IAEpE,IAAI,MAA6B,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,UAAU,CAAC;YACnB,MAAM,EAAE,mBAAmB;YAC3B,OAAO,EAAE,yBAAyB,SAAS,8CAA8C;YACzF,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAED,4BAA4B;IAC5B,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,CAAC,KAAK,CAAC,cAAc,CACzB,MAAM,EACN,CAAC,GAAiB,EAAE,EAAE;YACpB,IAAI,GAAG;gBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;;gBAChB,OAAO,EAAE,CAAC;QACjB,CAAC,EACD,CAAC,KAAuC,EAAE,EAAE;YAC1C,IACE,KAAK,CAAC,MAAM;gBACZ,KAAK,CAAC,MAAM,KAAK,aAAa;gBAC9B,KAAK,CAAC,MAAM,KAAK,YAAY,EAC7B,CAAC;gBACD,OAAO,CAAC,GAAG,CACT,YAAY,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAC5D,CAAC;YACJ,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,2BAA2B,SAAS,EAAE,CAAC,CAAC;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB;IACrD,MAAM,SAAS,GAAG,MAAM,WAAW,CAAC,SAAS,CAAC,CAAC;IAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error types for DevNet operations.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.2.0
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
declare const ClusterError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
|
|
8
|
+
readonly _tag: "ClusterError";
|
|
9
|
+
} & Readonly<A>;
|
|
10
|
+
/**
|
|
11
|
+
* Error thrown when cluster operations fail.
|
|
12
|
+
*
|
|
13
|
+
* @since 0.2.0
|
|
14
|
+
* @category errors
|
|
15
|
+
*/
|
|
16
|
+
export declare class ClusterError extends ClusterError_base<{
|
|
17
|
+
readonly operation: string;
|
|
18
|
+
readonly cluster?: string;
|
|
19
|
+
readonly cause: unknown;
|
|
20
|
+
}> {
|
|
21
|
+
}
|
|
22
|
+
declare const ContainerError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
|
|
23
|
+
readonly _tag: "ContainerError";
|
|
24
|
+
} & Readonly<A>;
|
|
25
|
+
/**
|
|
26
|
+
* Error thrown when container operations fail.
|
|
27
|
+
*
|
|
28
|
+
* @since 0.2.0
|
|
29
|
+
* @category errors
|
|
30
|
+
*/
|
|
31
|
+
export declare class ContainerError extends ContainerError_base<{
|
|
32
|
+
readonly operation: string;
|
|
33
|
+
readonly container: string;
|
|
34
|
+
readonly cause: unknown;
|
|
35
|
+
}> {
|
|
36
|
+
}
|
|
37
|
+
declare const HealthCheckError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
|
|
38
|
+
readonly _tag: "HealthCheckError";
|
|
39
|
+
} & Readonly<A>;
|
|
40
|
+
/**
|
|
41
|
+
* Error thrown when health check fails.
|
|
42
|
+
*
|
|
43
|
+
* @since 0.2.0
|
|
44
|
+
* @category errors
|
|
45
|
+
*/
|
|
46
|
+
export declare class HealthCheckError extends HealthCheckError_base<{
|
|
47
|
+
readonly service: string;
|
|
48
|
+
readonly cause: unknown;
|
|
49
|
+
}> {
|
|
50
|
+
}
|
|
51
|
+
declare const DockerNotRunningError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
|
|
52
|
+
readonly _tag: "DockerNotRunningError";
|
|
53
|
+
} & Readonly<A>;
|
|
54
|
+
/**
|
|
55
|
+
* Error thrown when Docker is not running.
|
|
56
|
+
*
|
|
57
|
+
* @since 0.2.0
|
|
58
|
+
* @category errors
|
|
59
|
+
*/
|
|
60
|
+
export declare class DockerNotRunningError extends DockerNotRunningError_base<{
|
|
61
|
+
readonly cause: unknown;
|
|
62
|
+
}> {
|
|
63
|
+
}
|
|
64
|
+
export {};
|
|
65
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/devnet/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;;;;AAIH;;;;;GAKG;AACH,qBAAa,YAAa,SAAQ,kBAAiC;IACjE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB,CAAC;CAAG;;;;AAEL;;;;;GAKG;AACH,qBAAa,cAAe,SAAQ,oBAAmC;IACrE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB,CAAC;CAAG;;;;AAEL;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,sBAAqC;IACzE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB,CAAC;CAAG;;;;AAEL;;;;;GAKG;AACH,qBAAa,qBAAsB,SAAQ,2BAA0C;IACnF,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB,CAAC;CAAG"}
|