@compforge/harness-toolbox 0.4.4 → 0.4.5
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/README.md +10 -0
- package/dist/chunk-835fssgz.js +37 -0
- package/dist/{chunk-0s27bgga.js → chunk-ae84rzq5.js} +1 -1
- package/dist/{chunk-age65q4n.js → chunk-db4an9td.js} +1 -1
- package/dist/{chunk-ftkrjqkc.js → chunk-dpcge1xt.js} +1 -1
- package/dist/{chunk-grpygk6f.js → chunk-dx6yvj81.js} +2 -2
- package/dist/{chunk-sqbew04a.js → chunk-f3vq900j.js} +2 -2
- package/dist/{chunk-yp6tcw22.js → chunk-f98qrpx1.js} +38 -78
- package/dist/{chunk-c2n8zvyn.js → chunk-g2bac2jd.js} +6 -6
- package/dist/chunk-gm4swndx.js +106 -0
- package/dist/{chunk-shsabpc1.js → chunk-r3rnsvwv.js} +1 -1
- package/dist/{chunk-20kv4wc3.js → chunk-rkt41za2.js} +7 -1
- package/dist/{chunk-8mb6natq.js → chunk-sbt20n84.js} +53 -35
- package/dist/{chunk-h73h2b7y.js → chunk-t4hrnaj0.js} +44 -39
- package/dist/{chunk-kkts16w9.js → chunk-ww11q58v.js} +1 -1
- package/dist/{chunk-4ms037k2.js → chunk-x0yhfg29.js} +2 -2
- package/dist/{chunk-5zgz1z41.js → chunk-z15gwjvg.js} +1 -1
- package/dist/connection/acquire.d.ts +34 -0
- package/dist/connection/acquire.js +9 -0
- package/dist/datasource.js +1 -1
- package/dist/errors.d.ts +4 -0
- package/dist/errors.js +3 -1
- package/dist/file/client.js +2 -2
- package/dist/file/index.js +4 -4
- package/dist/file/local.js +3 -3
- package/dist/file/pod.js +3 -3
- package/dist/kubernetes/client.js +6 -6
- package/dist/kubernetes/compute-quantity.js +2 -2
- package/dist/kubernetes/compute.js +2 -2
- package/dist/kubernetes/environment.js +6 -6
- package/dist/kubernetes/exec-transport.js +2 -2
- package/dist/kubernetes/pod-log-datasource.js +1 -1
- package/dist/kubernetes/resource-transport.js +3 -3
- package/dist/kubernetes/resources.js +2 -2
- package/dist/kubernetes/workload.js +2 -2
- package/dist/mysql/client.d.ts +5 -2
- package/dist/mysql/client.js +5 -4
- package/dist/mysql/connection.d.ts +3 -0
- package/dist/mysql/connection.js +4 -2
- package/dist/mysql/index.js +6 -5
- package/dist/mysql/readonly.js +2 -2
- package/dist/opensearch/client.d.ts +3 -1
- package/dist/opensearch/client.js +3 -2
- package/dist/opensearch/index.js +3 -2
- package/dist/redis/client.js +3 -2
- package/dist/redis/index.js +7 -6
- package/dist/s3/datasource.js +1 -1
- package/dist/s3/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-136egyff.js +0 -11
package/README.md
CHANGED
|
@@ -173,6 +173,9 @@ the root owns cancellation and must join child work before disposing clients.
|
|
|
173
173
|
|
|
174
174
|
Catch ToolboxError from the root entry or `@compforge/harness-toolbox/errors`; use `kind` and
|
|
175
175
|
`code` for decisions. Native `cause` may contain sensitive details and is debug-only.
|
|
176
|
+
Connection acquisition deadlines and Redis handshake/command deadlines raise `TimeoutError`
|
|
177
|
+
from `@compforge/harness-toolbox/errors`. It extends `ToolboxError`, retaining
|
|
178
|
+
`kind: "timeout"` and `code: "ETIMEDOUT"`; OpenSearch preserves it unchanged.
|
|
176
179
|
|
|
177
180
|
For coordinated common/toolbox development, install and build common before installing toolbox:
|
|
178
181
|
|
|
@@ -384,3 +387,10 @@ ResourceAccess, use explicit deadlines/item/page budgets, and retain read covera
|
|
|
384
387
|
Use `client.clusterResources()` for Nodes and all-namespace Pods; normal client methods retain their
|
|
385
388
|
configured namespace. A forbidden cluster read records `permission_denied`; it does not block a
|
|
386
389
|
separate namespace-scoped Workload read. See [compute collection](../../../docs/toolbox.md#kubernetes-compute-evidence).
|
|
390
|
+
|
|
391
|
+
### Connection acquisition deadlines
|
|
392
|
+
|
|
393
|
+
MySQL, OpenSearch and Redis use the same acquisition lifecycle. `connectTimeoutMs` includes route mapping
|
|
394
|
+
and handshake/probe; optional `acquireTimeoutMs` bounds all routes together (default: per-route budget × route count).
|
|
395
|
+
Cancellation preserves the caller reason and prevents late mappings from starting a handshake. Query and command
|
|
396
|
+
timeouts remain separate, and failed operations are never replayed on another transport.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// src/mysql/connection.ts
|
|
2
|
+
import { createConnection } from "mysql2";
|
|
3
|
+
async function connectMysql(options, signal) {
|
|
4
|
+
signal?.throwIfAborted();
|
|
5
|
+
const native = createConnection(options);
|
|
6
|
+
const connection = native.promise();
|
|
7
|
+
let abort;
|
|
8
|
+
try {
|
|
9
|
+
await new Promise((resolve, reject) => {
|
|
10
|
+
abort = () => {
|
|
11
|
+
destroyMysqlConnection(connection);
|
|
12
|
+
reject(signal.reason);
|
|
13
|
+
};
|
|
14
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
15
|
+
native.connect((error) => error ? reject(error) : resolve());
|
|
16
|
+
if (signal?.aborted)
|
|
17
|
+
abort();
|
|
18
|
+
});
|
|
19
|
+
signal?.throwIfAborted();
|
|
20
|
+
return connection;
|
|
21
|
+
} catch (error) {
|
|
22
|
+
destroyMysqlConnection(connection);
|
|
23
|
+
throw error;
|
|
24
|
+
} finally {
|
|
25
|
+
signal?.removeEventListener("abort", abort);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function destroyMysqlConnection(connection) {
|
|
29
|
+
const native = connection.connection;
|
|
30
|
+
try {
|
|
31
|
+
connection.destroy();
|
|
32
|
+
} finally {
|
|
33
|
+
native.stream.destroy();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { connectMysql, destroyMysqlConnection };
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
BoundedFileClient,
|
|
3
3
|
fileClientOptions,
|
|
4
4
|
filePaths
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ww11q58v.js";
|
|
6
6
|
import {
|
|
7
7
|
FileError
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-rkt41za2.js";
|
|
9
9
|
|
|
10
10
|
// src/file/pod.ts
|
|
11
11
|
import { posix } from "node:path";
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
BoundedFileClient,
|
|
3
3
|
fileClientOptions,
|
|
4
4
|
filePaths
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ww11q58v.js";
|
|
6
6
|
import {
|
|
7
7
|
FileError
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-rkt41za2.js";
|
|
9
9
|
|
|
10
10
|
// src/file/local.ts
|
|
11
11
|
import { constants } from "node:fs";
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
acquireConnection,
|
|
3
|
+
awaitWithSignal
|
|
4
|
+
} from "./chunk-gm4swndx.js";
|
|
1
5
|
import {
|
|
2
6
|
discoverRedisTopology
|
|
3
7
|
} from "./chunk-5tbzf9wd.js";
|
|
4
8
|
import {
|
|
5
|
-
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
TimeoutError
|
|
10
|
+
} from "./chunk-rkt41za2.js";
|
|
7
11
|
import {
|
|
8
12
|
isConnectionNetworkError
|
|
9
13
|
} from "./chunk-h8fwx0k7.js";
|
|
@@ -41,26 +45,6 @@ function parseRedisInfo(raw) {
|
|
|
41
45
|
}
|
|
42
46
|
return result;
|
|
43
47
|
}
|
|
44
|
-
async function abortable(pending, signal, cancel) {
|
|
45
|
-
if (signal.aborted) {
|
|
46
|
-
cancel?.();
|
|
47
|
-
pending.catch(() => {});
|
|
48
|
-
signal.throwIfAborted();
|
|
49
|
-
}
|
|
50
|
-
let abort;
|
|
51
|
-
const cancelled = new Promise((_, reject) => {
|
|
52
|
-
abort = () => {
|
|
53
|
-
cancel?.();
|
|
54
|
-
reject(signal.reason);
|
|
55
|
-
};
|
|
56
|
-
signal.addEventListener("abort", abort, { once: true });
|
|
57
|
-
});
|
|
58
|
-
try {
|
|
59
|
-
return await Promise.race([pending, cancelled]);
|
|
60
|
-
} finally {
|
|
61
|
-
signal.removeEventListener("abort", abort);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
48
|
|
|
65
49
|
class RedisConnection {
|
|
66
50
|
endpoint;
|
|
@@ -101,7 +85,7 @@ class RedisConnection {
|
|
|
101
85
|
lastError = err instanceof Error ? err : new Error(String(err));
|
|
102
86
|
});
|
|
103
87
|
const timeout = new AbortController;
|
|
104
|
-
const timer = setTimeout(() => timeout.abort(new
|
|
88
|
+
const timer = setTimeout(() => timeout.abort(new TimeoutError("Redis handshake timed out")), config.connectTimeoutMs ?? config.timeoutMs);
|
|
105
89
|
const signal = AbortSignal.any([
|
|
106
90
|
timeout.signal,
|
|
107
91
|
...config.signal ? [config.signal] : [],
|
|
@@ -112,7 +96,7 @@ class RedisConnection {
|
|
|
112
96
|
client.destroy();
|
|
113
97
|
};
|
|
114
98
|
try {
|
|
115
|
-
await
|
|
99
|
+
await awaitWithSignal(client.connect(), signal, close);
|
|
116
100
|
signal.throwIfAborted();
|
|
117
101
|
return new RedisConnection(endpoint, client, config.timeoutMs, () => lastError, config.signal);
|
|
118
102
|
} catch (error) {
|
|
@@ -132,10 +116,10 @@ class RedisConnection {
|
|
|
132
116
|
throw new Error(`Redis connection is closed${reason ? `: ${reason}` : ""}`);
|
|
133
117
|
}
|
|
134
118
|
const timeout = new AbortController;
|
|
135
|
-
const timer = setTimeout(() => timeout.abort(new
|
|
119
|
+
const timer = setTimeout(() => timeout.abort(new TimeoutError(`Redis ${operationName} timed out after ${this.timeoutMs}ms (${this.endpoint.host}:${this.endpoint.port})`)), this.timeoutMs);
|
|
136
120
|
const signal = this.signal ? AbortSignal.any([this.signal, timeout.signal]) : timeout.signal;
|
|
137
121
|
try {
|
|
138
|
-
return await
|
|
122
|
+
return await awaitWithSignal(Promise.resolve().then(() => {
|
|
139
123
|
signal.throwIfAborted();
|
|
140
124
|
return operation();
|
|
141
125
|
}), signal, () => this.close());
|
|
@@ -229,58 +213,34 @@ class RedisAccess {
|
|
|
229
213
|
});
|
|
230
214
|
return pending;
|
|
231
215
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
});
|
|
259
|
-
const prepared = pending.then((connection2) => {
|
|
260
|
-
if (attemptSignal.aborted) {
|
|
261
|
-
connection2.close();
|
|
262
|
-
attemptSignal.throwIfAborted();
|
|
263
|
-
}
|
|
264
|
-
return connection2;
|
|
265
|
-
});
|
|
266
|
-
const connection = await abortable(prepared, attemptSignal);
|
|
267
|
-
this.lifecycle.onRoute?.({ transport: mapped.host === endpoint.host && mapped.port === endpoint.port ? "direct" : transport.name, reason });
|
|
268
|
-
return connection;
|
|
269
|
-
} catch (failure) {
|
|
270
|
-
signal.throwIfAborted();
|
|
271
|
-
const error = attemptSignal.aborted ? attemptSignal.reason : failure;
|
|
272
|
-
const network = isConnectionNetworkError(error) || error instanceof SocketClosedUnexpectedlyError || error instanceof ConnectionTimeoutError;
|
|
273
|
-
if (!network || index === this.#transports.length - 1)
|
|
274
|
-
throw error;
|
|
275
|
-
reason = error instanceof SocketClosedUnexpectedlyError ? "connection_lost" : error instanceof ConnectionTimeoutError ? "ETIMEDOUT" : String(error.code);
|
|
276
|
-
} finally {
|
|
277
|
-
clearTimeout(attemptTimer);
|
|
278
|
-
}
|
|
216
|
+
#open(endpoint, database, credentials) {
|
|
217
|
+
return acquireConnection(this.#transports, {
|
|
218
|
+
name: "Redis connection",
|
|
219
|
+
signal: this.#signal,
|
|
220
|
+
connectTimeoutMs: this.baseConfig.connectTimeoutMs ?? this.baseConfig.timeoutMs,
|
|
221
|
+
acquireTimeoutMs: this.baseConfig.acquireTimeoutMs,
|
|
222
|
+
onRoute: this.lifecycle.onRoute,
|
|
223
|
+
open: async (transport, attempt) => {
|
|
224
|
+
const mapped = await transport.connect(endpoint);
|
|
225
|
+
const connection = await this.connectionFactory(endpoint, mapped, {
|
|
226
|
+
...this.baseConfig,
|
|
227
|
+
...credentials,
|
|
228
|
+
database,
|
|
229
|
+
connectTimeoutMs: attempt.remainingMs(),
|
|
230
|
+
signal: this.#signal,
|
|
231
|
+
connectSignal: attempt.signal
|
|
232
|
+
});
|
|
233
|
+
return { connection, transport: mapped.host === endpoint.host && mapped.port === endpoint.port ? "direct" : transport.name };
|
|
234
|
+
},
|
|
235
|
+
close: (connection) => connection.close(),
|
|
236
|
+
retryReason: (error) => {
|
|
237
|
+
if (error instanceof SocketClosedUnexpectedlyError)
|
|
238
|
+
return "connection_lost";
|
|
239
|
+
if (error instanceof ConnectionTimeoutError)
|
|
240
|
+
return "ETIMEDOUT";
|
|
241
|
+
return isConnectionNetworkError(error) ? String(error.code) : undefined;
|
|
279
242
|
}
|
|
280
|
-
|
|
281
|
-
} finally {
|
|
282
|
-
clearTimeout(timer);
|
|
283
|
-
}
|
|
243
|
+
});
|
|
284
244
|
}
|
|
285
245
|
close() {
|
|
286
246
|
return this.#closing ??= (async () => {
|
|
@@ -319,7 +279,7 @@ class RedisClient {
|
|
|
319
279
|
initialize() {
|
|
320
280
|
this.signal.throwIfAborted();
|
|
321
281
|
return this.#initialization ??= (async () => {
|
|
322
|
-
this.#target = await this.source.resolve();
|
|
282
|
+
this.#target = await awaitWithSignal(this.source.resolve(), this.signal);
|
|
323
283
|
this.signal.throwIfAborted();
|
|
324
284
|
if (!this.source.transports.length || this.source.transports.some((transport) => transport.kind !== "tcp")) {
|
|
325
285
|
throw new Error("Redis requires TCP transports");
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveWorkload
|
|
3
|
+
} from "./chunk-ae84rzq5.js";
|
|
1
4
|
import {
|
|
2
5
|
ServicePortForwarder
|
|
3
6
|
} from "./chunk-2171tajs.js";
|
|
4
7
|
import {
|
|
5
8
|
KubernetesResourceTransport
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-x0yhfg29.js";
|
|
7
10
|
import {
|
|
8
11
|
KubernetesExecTransport
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import {
|
|
11
|
-
resolveWorkload
|
|
12
|
-
} from "./chunk-0s27bgga.js";
|
|
12
|
+
} from "./chunk-r3rnsvwv.js";
|
|
13
13
|
import {
|
|
14
14
|
KubernetesError
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-rkt41za2.js";
|
|
16
16
|
import {
|
|
17
17
|
KubectlExecutor
|
|
18
18
|
} from "./chunk-hmah9t8e.js";
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TimeoutError,
|
|
3
|
+
ToolboxError
|
|
4
|
+
} from "./chunk-rkt41za2.js";
|
|
5
|
+
|
|
6
|
+
// src/connection/acquire.ts
|
|
7
|
+
async function awaitWithSignal(pending, signal, cancel) {
|
|
8
|
+
if (signal.aborted) {
|
|
9
|
+
cancel?.();
|
|
10
|
+
pending.catch(() => {});
|
|
11
|
+
signal.throwIfAborted();
|
|
12
|
+
}
|
|
13
|
+
let abort;
|
|
14
|
+
const cancelled = new Promise((_, reject) => {
|
|
15
|
+
abort = () => {
|
|
16
|
+
cancel?.();
|
|
17
|
+
reject(signal.reason);
|
|
18
|
+
};
|
|
19
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
20
|
+
});
|
|
21
|
+
try {
|
|
22
|
+
return await Promise.race([pending, cancelled]);
|
|
23
|
+
} finally {
|
|
24
|
+
signal.removeEventListener("abort", abort);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function acquireConnection(routes, options) {
|
|
28
|
+
const budget = options.acquireTimeoutMs ?? options.connectTimeoutMs * routes.length;
|
|
29
|
+
if (!routes.length)
|
|
30
|
+
throw new ToolboxError(`${options.name} requires a transport`, { kind: "invalid_argument" });
|
|
31
|
+
if ([options.connectTimeoutMs, budget].some((value) => !Number.isFinite(value) || value <= 0 || value > 2147483647)) {
|
|
32
|
+
throw new ToolboxError(`${options.name} timeouts must be positive milliseconds within timer range`, { kind: "invalid_argument" });
|
|
33
|
+
}
|
|
34
|
+
options.signal?.throwIfAborted();
|
|
35
|
+
const timeout = new AbortController;
|
|
36
|
+
const timedOut = (message) => new TimeoutError(message);
|
|
37
|
+
const deadline = performance.now() + budget;
|
|
38
|
+
const timer = setTimeout(() => timeout.abort(timedOut(`${options.name} timed out after ${budget}ms`)), budget);
|
|
39
|
+
const signal = options.signal ? AbortSignal.any([options.signal, timeout.signal]) : timeout.signal;
|
|
40
|
+
let reason;
|
|
41
|
+
try {
|
|
42
|
+
for (const [index, route] of routes.entries()) {
|
|
43
|
+
if (performance.now() >= deadline)
|
|
44
|
+
timeout.abort(timedOut(`${options.name} timed out after ${budget}ms`));
|
|
45
|
+
signal.throwIfAborted();
|
|
46
|
+
const attempt = new AbortController;
|
|
47
|
+
const end = Math.min(deadline, performance.now() + options.connectTimeoutMs);
|
|
48
|
+
const expire = () => attempt.abort(timedOut(`${options.name} attempt timed out (${route.name})`));
|
|
49
|
+
const attemptTimer = setTimeout(expire, Math.max(1, Math.ceil(end - performance.now())));
|
|
50
|
+
const attemptSignal = AbortSignal.any([signal, attempt.signal]);
|
|
51
|
+
const context = {
|
|
52
|
+
signal: attemptSignal,
|
|
53
|
+
remainingMs: () => {
|
|
54
|
+
if (performance.now() >= end)
|
|
55
|
+
expire();
|
|
56
|
+
attemptSignal.throwIfAborted();
|
|
57
|
+
return Math.max(1, Math.ceil(end - performance.now()));
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
let candidate;
|
|
61
|
+
let discarded = false;
|
|
62
|
+
const discard = async () => {
|
|
63
|
+
if (!candidate || discarded)
|
|
64
|
+
return;
|
|
65
|
+
discarded = true;
|
|
66
|
+
await options.close(candidate.connection);
|
|
67
|
+
};
|
|
68
|
+
let result;
|
|
69
|
+
try {
|
|
70
|
+
const prepared = options.open(route, context).then(async (value) => {
|
|
71
|
+
candidate = value;
|
|
72
|
+
if (attemptSignal.aborted) {
|
|
73
|
+
await discard();
|
|
74
|
+
attemptSignal.throwIfAborted();
|
|
75
|
+
}
|
|
76
|
+
return value;
|
|
77
|
+
});
|
|
78
|
+
result = await awaitWithSignal(prepared, attemptSignal);
|
|
79
|
+
} catch (failure) {
|
|
80
|
+
await discard();
|
|
81
|
+
signal.throwIfAborted();
|
|
82
|
+
const error = attemptSignal.aborted ? attemptSignal.reason : failure;
|
|
83
|
+
reason = options.retryReason(error);
|
|
84
|
+
if (reason === undefined || index === routes.length - 1)
|
|
85
|
+
throw error;
|
|
86
|
+
continue;
|
|
87
|
+
} finally {
|
|
88
|
+
clearTimeout(attemptTimer);
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
attemptSignal.throwIfAborted();
|
|
92
|
+
options.onRoute?.({ transport: result.transport, reason });
|
|
93
|
+
attemptSignal.throwIfAborted();
|
|
94
|
+
return result.connection;
|
|
95
|
+
} catch (error) {
|
|
96
|
+
await discard();
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
throw new Error("Connection routes exhausted");
|
|
101
|
+
} finally {
|
|
102
|
+
clearTimeout(timer);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export { awaitWithSignal, acquireConnection };
|
|
@@ -15,6 +15,12 @@ class KubernetesError extends ToolboxError {
|
|
|
15
15
|
|
|
16
16
|
class FileError extends ToolboxError {
|
|
17
17
|
}
|
|
18
|
+
|
|
19
|
+
class TimeoutError extends ToolboxError {
|
|
20
|
+
constructor(message, options) {
|
|
21
|
+
super(message, { kind: "timeout", code: "ETIMEDOUT", cause: options?.cause });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
18
24
|
function kubernetesHttpError(status) {
|
|
19
25
|
const kind = {
|
|
20
26
|
401: "authentication_failed",
|
|
@@ -41,4 +47,4 @@ function kubernetesCommandError(result) {
|
|
|
41
47
|
return status ? kubernetesHttpError(status) : new KubernetesError("Kubernetes resource request failed", { kind: "operation_failed" });
|
|
42
48
|
}
|
|
43
49
|
|
|
44
|
-
export { ToolboxError, KubernetesError, FileError, kubernetesHttpError, kubernetesCommandError };
|
|
50
|
+
export { ToolboxError, KubernetesError, FileError, TimeoutError, kubernetesHttpError, kubernetesCommandError };
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
acquireConnection,
|
|
3
|
+
awaitWithSignal
|
|
4
|
+
} from "./chunk-gm4swndx.js";
|
|
1
5
|
import {
|
|
2
6
|
ToolboxError
|
|
3
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-rkt41za2.js";
|
|
4
8
|
import {
|
|
5
9
|
isConnectionNetworkError
|
|
6
10
|
} from "./chunk-h8fwx0k7.js";
|
|
@@ -68,6 +72,15 @@ class OpenSearchEngine {
|
|
|
68
72
|
return this.client.close();
|
|
69
73
|
}
|
|
70
74
|
}
|
|
75
|
+
function openSearchRetryReason(error) {
|
|
76
|
+
if (isConnectionNetworkError(error))
|
|
77
|
+
return String(error.code);
|
|
78
|
+
if (error instanceof errors.TimeoutError)
|
|
79
|
+
return "ETIMEDOUT";
|
|
80
|
+
if (error instanceof errors.ConnectionError)
|
|
81
|
+
return error.name;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
71
84
|
|
|
72
85
|
class OpenSearchClient {
|
|
73
86
|
source;
|
|
@@ -86,44 +99,49 @@ class OpenSearchClient {
|
|
|
86
99
|
initialize() {
|
|
87
100
|
this.signal.throwIfAborted();
|
|
88
101
|
return this.#initialization ??= (async () => {
|
|
89
|
-
const target = await this.source.resolve();
|
|
102
|
+
const target = await awaitWithSignal(this.source.resolve(), this.signal);
|
|
90
103
|
this.signal.throwIfAborted();
|
|
91
104
|
const original = new URL(target.node);
|
|
92
|
-
|
|
93
|
-
|
|
105
|
+
try {
|
|
106
|
+
this.#engine = await acquireConnection(this.source.transports, {
|
|
107
|
+
name: "OpenSearch connection",
|
|
108
|
+
signal: this.signal,
|
|
109
|
+
connectTimeoutMs: target.connectTimeoutMs ?? target.requestTimeoutMs ?? 1e4,
|
|
110
|
+
acquireTimeoutMs: target.acquireTimeoutMs,
|
|
111
|
+
onRoute: this.lifecycle.onRoute,
|
|
112
|
+
open: async (transport, attempt) => {
|
|
113
|
+
if (transport.kind !== "tcp")
|
|
114
|
+
throw new Error("OpenSearch requires a TCP transport");
|
|
115
|
+
const endpoint = await transport.connect({
|
|
116
|
+
host: original.hostname,
|
|
117
|
+
port: Number(original.port || (original.protocol === "https:" ? 443 : 80)),
|
|
118
|
+
servername: target.servername ?? original.hostname
|
|
119
|
+
});
|
|
120
|
+
attempt.signal.throwIfAborted();
|
|
121
|
+
const url = new URL(original);
|
|
122
|
+
url.hostname = endpoint.host;
|
|
123
|
+
url.port = String(endpoint.port);
|
|
124
|
+
const engine = new OpenSearchEngine({ ...target, node: url.toString(), servername: endpoint.servername ?? target.servername ?? original.hostname });
|
|
125
|
+
try {
|
|
126
|
+
await engine.ping(attempt.signal, attempt.remainingMs());
|
|
127
|
+
return { connection: engine, transport: transport.name };
|
|
128
|
+
} catch (error) {
|
|
129
|
+
await engine.close();
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
close: (engine) => engine.close(),
|
|
134
|
+
retryReason: openSearchRetryReason
|
|
135
|
+
});
|
|
136
|
+
} catch (error) {
|
|
94
137
|
this.signal.throwIfAborted();
|
|
95
|
-
if (
|
|
96
|
-
throw
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
port: Number(original.port || (original.protocol === "https:" ? 443 : 80)),
|
|
102
|
-
servername: target.servername ?? original.hostname
|
|
103
|
-
});
|
|
104
|
-
this.signal.throwIfAborted();
|
|
105
|
-
const url = new URL(original);
|
|
106
|
-
url.hostname = endpoint.host;
|
|
107
|
-
url.port = String(endpoint.port);
|
|
108
|
-
engine = new OpenSearchEngine({ ...target, node: url.toString(), servername: endpoint.servername ?? target.servername ?? original.hostname });
|
|
109
|
-
await engine.ping(this.signal, target.connectTimeoutMs ?? target.requestTimeoutMs ?? 1e4);
|
|
110
|
-
this.signal.throwIfAborted();
|
|
111
|
-
this.lifecycle.onRoute?.({ transport: transport.name, reason });
|
|
112
|
-
this.#engine = engine;
|
|
113
|
-
return;
|
|
114
|
-
} catch (error) {
|
|
115
|
-
await engine?.close();
|
|
116
|
-
this.signal.throwIfAborted();
|
|
117
|
-
const network = isConnectionNetworkError(error);
|
|
118
|
-
if (!network && !(error instanceof errors.ConnectionError) && !(error instanceof errors.TimeoutError))
|
|
119
|
-
throw error;
|
|
120
|
-
reason = network ? String(error.code) : error.name;
|
|
121
|
-
if (index === this.source.transports.length - 1) {
|
|
122
|
-
throw new ToolboxError(`OpenSearch connect failed (${reason})`, { kind: "connection_failed", code: reason, cause: error });
|
|
123
|
-
}
|
|
124
|
-
}
|
|
138
|
+
if (error instanceof ToolboxError && error.kind === "timeout")
|
|
139
|
+
throw error;
|
|
140
|
+
const reason = openSearchRetryReason(error);
|
|
141
|
+
if (reason === undefined)
|
|
142
|
+
throw error;
|
|
143
|
+
throw new ToolboxError(`OpenSearch connect failed (${reason})`, { kind: "connection_failed", code: reason, cause: error });
|
|
125
144
|
}
|
|
126
|
-
throw new Error("OpenSearch DataSource has no transport");
|
|
127
145
|
})();
|
|
128
146
|
}
|
|
129
147
|
#ready() {
|
|
@@ -5,13 +5,18 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
queryReadonlySession,
|
|
7
7
|
validateQueryLimits
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-db4an9td.js";
|
|
9
9
|
import {
|
|
10
|
+
connectMysql,
|
|
10
11
|
destroyMysqlConnection
|
|
11
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-835fssgz.js";
|
|
13
|
+
import {
|
|
14
|
+
acquireConnection,
|
|
15
|
+
awaitWithSignal
|
|
16
|
+
} from "./chunk-gm4swndx.js";
|
|
12
17
|
import {
|
|
13
18
|
ToolboxError
|
|
14
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-rkt41za2.js";
|
|
15
20
|
import {
|
|
16
21
|
ConcurrencyPool
|
|
17
22
|
} from "./chunk-v3hxvnrc.js";
|
|
@@ -20,7 +25,6 @@ import {
|
|
|
20
25
|
} from "./chunk-h8fwx0k7.js";
|
|
21
26
|
|
|
22
27
|
// src/mysql/client.ts
|
|
23
|
-
import { createConnection } from "mysql2/promise";
|
|
24
28
|
function mysqlOperationError(error, phase) {
|
|
25
29
|
if (!error || typeof error !== "object" || !("code" in error) || error.code !== "PROTOCOL_CONNECTION_LOST")
|
|
26
30
|
return error;
|
|
@@ -37,7 +41,7 @@ class MysqlDatabase {
|
|
|
37
41
|
connect;
|
|
38
42
|
#queries = new ConcurrencyPool(1);
|
|
39
43
|
#connections = new Map;
|
|
40
|
-
constructor(transports, options, connect =
|
|
44
|
+
constructor(transports, options, connect = connectMysql) {
|
|
41
45
|
this.transports = transports;
|
|
42
46
|
this.options = options;
|
|
43
47
|
this.connect = connect;
|
|
@@ -120,39 +124,40 @@ class MysqlDatabase {
|
|
|
120
124
|
return rows;
|
|
121
125
|
});
|
|
122
126
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
127
|
+
#open(target) {
|
|
128
|
+
return acquireConnection(this.transports, {
|
|
129
|
+
name: "MySQL connection",
|
|
130
|
+
...this.options,
|
|
131
|
+
open: async (transport, attempt) => {
|
|
132
|
+
if (transport.kind === "python")
|
|
133
|
+
return { connection: { kind: "python", transport }, transport: transport.name };
|
|
134
|
+
try {
|
|
135
|
+
const endpoint = await transport.connect(target);
|
|
136
|
+
const connection = await this.connect({
|
|
137
|
+
host: endpoint.host,
|
|
138
|
+
port: endpoint.port,
|
|
139
|
+
user: target.user,
|
|
140
|
+
password: target.password,
|
|
141
|
+
database: target.database,
|
|
142
|
+
connectTimeout: attempt.remainingMs(),
|
|
143
|
+
dateStrings: true,
|
|
144
|
+
supportBigNumbers: true,
|
|
145
|
+
bigNumberStrings: true
|
|
146
|
+
}, attempt.signal);
|
|
147
|
+
return {
|
|
148
|
+
connection: { kind: "tcp", connection },
|
|
149
|
+
transport: endpoint.host === target.host && endpoint.port === target.port ? "direct" : transport.name
|
|
150
|
+
};
|
|
151
|
+
} catch (error) {
|
|
152
|
+
throw mysqlOperationError(error, "connect");
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
close: (session) => {
|
|
156
|
+
if (session.kind === "tcp")
|
|
157
|
+
destroyMysqlConnection(session.connection);
|
|
158
|
+
},
|
|
159
|
+
retryReason: (error) => isConnectionNetworkError(error) || error instanceof ToolboxError && error.kind === "connection_lost" ? String(error.code) : undefined
|
|
160
|
+
});
|
|
156
161
|
}
|
|
157
162
|
async queryOne(target, sql, values) {
|
|
158
163
|
return (await this.query(target, sql, values))[0];
|
|
@@ -186,7 +191,7 @@ class MysqlClient {
|
|
|
186
191
|
initialize() {
|
|
187
192
|
this.signal.throwIfAborted();
|
|
188
193
|
return this.#initialization ??= (async () => {
|
|
189
|
-
this.#target = await this.source.resolve();
|
|
194
|
+
this.#target = await awaitWithSignal(this.source.resolve(), this.signal);
|
|
190
195
|
this.signal.throwIfAborted();
|
|
191
196
|
this.#database = new MysqlDatabase(this.source.transports, { ...this.options, signal: this.signal });
|
|
192
197
|
await this.#database.initialize(this.#target);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resourcePath
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-dpcge1xt.js";
|
|
4
4
|
import {
|
|
5
5
|
clientKey
|
|
6
6
|
} from "./chunk-a9htb6cr.js";
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
KubernetesError,
|
|
9
9
|
ToolboxError,
|
|
10
10
|
kubernetesHttpError
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-rkt41za2.js";
|
|
12
12
|
import {
|
|
13
13
|
ConcurrencyPool
|
|
14
14
|
} from "./chunk-v3hxvnrc.js";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ClientLifecycle } from "../datasource";
|
|
2
|
+
/** Stop waiting without leaving rejected preparation promises unobserved. */
|
|
3
|
+
export declare function awaitWithSignal<T>(pending: Promise<T>, signal: AbortSignal, cancel?: () => void): Promise<T>;
|
|
4
|
+
export interface ConnectionAttempt {
|
|
5
|
+
readonly signal: AbortSignal;
|
|
6
|
+
/** Remaining mapping + handshake budget, not a fresh timeout for each phase. */
|
|
7
|
+
remainingMs(): number;
|
|
8
|
+
}
|
|
9
|
+
interface Acquisition<R, C> {
|
|
10
|
+
name: string;
|
|
11
|
+
connectTimeoutMs: number;
|
|
12
|
+
acquireTimeoutMs?: number;
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
open(route: R, attempt: ConnectionAttempt): Promise<{
|
|
15
|
+
connection: C;
|
|
16
|
+
transport: string;
|
|
17
|
+
}>;
|
|
18
|
+
close(connection: C): void | Promise<void>;
|
|
19
|
+
/** Undefined means terminal; authentication and protocol errors must not change route. */
|
|
20
|
+
retryReason(error: unknown): string | undefined;
|
|
21
|
+
onRoute?: ClientLifecycle["onRoute"];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* @spec One acquisition owns ordered attempts and a deadline covering mapping and handshake.
|
|
25
|
+
* @spec Cancellation keeps its original reason; a late successful connection is closed, never published.
|
|
26
|
+
* @rule Only connection preparation enters this function. Commands and queries must never be replayed.
|
|
27
|
+
* @why Protocol adapters own partial handles and error classification; all protocols share the same lifecycle.
|
|
28
|
+
* @see {@link component://docs/toolbox.md}
|
|
29
|
+
* @case id=connection_mapping_cancel,desc=`Cancel while mapping a route`,expect=`Acquisition exits without a late handshake`
|
|
30
|
+
*/
|
|
31
|
+
export declare function acquireConnection<R extends {
|
|
32
|
+
readonly name: string;
|
|
33
|
+
}, C>(routes: readonly R[], options: Acquisition<R, C>): Promise<C>;
|
|
34
|
+
export {};
|
package/dist/datasource.js
CHANGED
package/dist/errors.d.ts
CHANGED
|
@@ -13,6 +13,10 @@ export declare class KubernetesError extends ToolboxError {
|
|
|
13
13
|
}
|
|
14
14
|
export declare class FileError extends ToolboxError {
|
|
15
15
|
}
|
|
16
|
+
/** A local deadline expiry, distinct from a connection failure reported by a driver. */
|
|
17
|
+
export declare class TimeoutError extends ToolboxError {
|
|
18
|
+
constructor(message: string, options?: ErrorOptions);
|
|
19
|
+
}
|
|
16
20
|
export declare function kubernetesHttpError(status: number): KubernetesError;
|
|
17
21
|
/**
|
|
18
22
|
* Normalize a failed kubectl resource request at the transport boundary.
|
package/dist/errors.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
FileError,
|
|
3
3
|
KubernetesError,
|
|
4
|
+
TimeoutError,
|
|
4
5
|
ToolboxError,
|
|
5
6
|
kubernetesCommandError,
|
|
6
7
|
kubernetesHttpError
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-rkt41za2.js";
|
|
8
9
|
export {
|
|
9
10
|
kubernetesHttpError,
|
|
10
11
|
kubernetesCommandError,
|
|
11
12
|
ToolboxError,
|
|
13
|
+
TimeoutError,
|
|
12
14
|
KubernetesError,
|
|
13
15
|
FileError
|
|
14
16
|
};
|
package/dist/file/client.js
CHANGED
package/dist/file/index.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PodFileClient,
|
|
3
3
|
PodFileDataSource
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-dx6yvj81.js";
|
|
5
5
|
import {
|
|
6
6
|
LocalFileClient,
|
|
7
7
|
LocalFileDataSource
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import"../chunk-
|
|
8
|
+
} from "../chunk-f3vq900j.js";
|
|
9
|
+
import"../chunk-ww11q58v.js";
|
|
10
10
|
import {
|
|
11
11
|
FileError
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-rkt41za2.js";
|
|
13
13
|
import"../chunk-v3hxvnrc.js";
|
|
14
14
|
|
|
15
15
|
// src/file/index.ts
|
package/dist/file/local.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
LocalFileClient,
|
|
3
3
|
LocalFileDataSource
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import"../chunk-
|
|
6
|
-
import"../chunk-
|
|
4
|
+
} from "../chunk-f3vq900j.js";
|
|
5
|
+
import"../chunk-ww11q58v.js";
|
|
6
|
+
import"../chunk-rkt41za2.js";
|
|
7
7
|
import"../chunk-v3hxvnrc.js";
|
|
8
8
|
export {
|
|
9
9
|
LocalFileDataSource,
|
package/dist/file/pod.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PodFileClient,
|
|
3
3
|
PodFileDataSource
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import"../chunk-
|
|
6
|
-
import"../chunk-
|
|
4
|
+
} from "../chunk-dx6yvj81.js";
|
|
5
|
+
import"../chunk-ww11q58v.js";
|
|
6
|
+
import"../chunk-rkt41za2.js";
|
|
7
7
|
import"../chunk-v3hxvnrc.js";
|
|
8
8
|
export {
|
|
9
9
|
PodFileDataSource,
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
KubernetesClient
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-g2bac2jd.js";
|
|
4
|
+
import"../chunk-ae84rzq5.js";
|
|
4
5
|
import"../chunk-2171tajs.js";
|
|
5
6
|
import"../chunk-j46x7j7c.js";
|
|
6
7
|
import"../chunk-6fnhzhdb.js";
|
|
7
|
-
import"../chunk-
|
|
8
|
-
import"../chunk-
|
|
9
|
-
import"../chunk-
|
|
10
|
-
import"../chunk-0s27bgga.js";
|
|
8
|
+
import"../chunk-x0yhfg29.js";
|
|
9
|
+
import"../chunk-dpcge1xt.js";
|
|
10
|
+
import"../chunk-r3rnsvwv.js";
|
|
11
11
|
import"../chunk-a9htb6cr.js";
|
|
12
|
-
import"../chunk-
|
|
12
|
+
import"../chunk-rkt41za2.js";
|
|
13
13
|
import"../chunk-v3hxvnrc.js";
|
|
14
14
|
import"../chunk-631vce5z.js";
|
|
15
15
|
import"../chunk-hmah9t8e.js";
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
requiredString,
|
|
7
7
|
sum,
|
|
8
8
|
summarizePods
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-z15gwjvg.js";
|
|
10
10
|
import {
|
|
11
11
|
KubernetesError
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-rkt41za2.js";
|
|
13
13
|
|
|
14
14
|
// src/kubernetes/compute.ts
|
|
15
15
|
function requestBudget(options) {
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
KubernetesClient
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-g2bac2jd.js";
|
|
4
|
+
import"../chunk-ae84rzq5.js";
|
|
4
5
|
import"../chunk-2171tajs.js";
|
|
5
6
|
import"../chunk-j46x7j7c.js";
|
|
6
7
|
import"../chunk-6fnhzhdb.js";
|
|
7
|
-
import"../chunk-
|
|
8
|
-
import"../chunk-
|
|
9
|
-
import"../chunk-
|
|
10
|
-
import"../chunk-0s27bgga.js";
|
|
8
|
+
import"../chunk-x0yhfg29.js";
|
|
9
|
+
import"../chunk-dpcge1xt.js";
|
|
10
|
+
import"../chunk-r3rnsvwv.js";
|
|
11
11
|
import {
|
|
12
12
|
clientKey
|
|
13
13
|
} from "../chunk-a9htb6cr.js";
|
|
14
|
-
import"../chunk-
|
|
14
|
+
import"../chunk-rkt41za2.js";
|
|
15
15
|
import"../chunk-v3hxvnrc.js";
|
|
16
16
|
import"../chunk-631vce5z.js";
|
|
17
17
|
import"../chunk-hmah9t8e.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
KubernetesResourceTransport
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import"../chunk-
|
|
3
|
+
} from "../chunk-x0yhfg29.js";
|
|
4
|
+
import"../chunk-dpcge1xt.js";
|
|
5
5
|
import"../chunk-a9htb6cr.js";
|
|
6
|
-
import"../chunk-
|
|
6
|
+
import"../chunk-rkt41za2.js";
|
|
7
7
|
import"../chunk-v3hxvnrc.js";
|
|
8
8
|
export {
|
|
9
9
|
KubernetesResourceTransport
|
package/dist/mysql/client.d.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import type { Client } from "../client";
|
|
2
|
-
import {
|
|
2
|
+
import type { Connection, ConnectionOptions } from "mysql2/promise";
|
|
3
3
|
import type { Database, DatabaseTarget, DatabaseRow, DatabaseQueryLimits, DatabaseQueryResult, SqlStatement } from "./types";
|
|
4
4
|
import type { ConnectionSource, ClientLifecycle } from "../datasource";
|
|
5
5
|
import { type Transport } from "../transport";
|
|
6
6
|
export interface MysqlDatabaseOptions extends ClientLifecycle {
|
|
7
|
+
/** Per-route mapping and handshake budget. */
|
|
7
8
|
connectTimeoutMs: number;
|
|
9
|
+
/** Total acquisition budget; defaults to connectTimeoutMs times the route count. */
|
|
10
|
+
acquireTimeoutMs?: number;
|
|
8
11
|
queryTimeoutMs: number;
|
|
9
12
|
}
|
|
10
|
-
type ConnectionFactory = (options: ConnectionOptions) => Promise<Connection>;
|
|
13
|
+
type ConnectionFactory = (options: ConnectionOptions, signal?: AbortSignal) => Promise<Connection>;
|
|
11
14
|
/**
|
|
12
15
|
* @spec SQL is executed once; only native connection establishment may advance to another transport.
|
|
13
16
|
* @why mysql2 reports a socket closed during handshake as PROTOCOL_CONNECTION_LOST, before any SQL is sent.
|
package/dist/mysql/client.js
CHANGED
|
@@ -2,11 +2,12 @@ import {
|
|
|
2
2
|
MysqlClient,
|
|
3
3
|
MysqlDatabase,
|
|
4
4
|
openMysql
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-t4hrnaj0.js";
|
|
6
6
|
import"../chunk-m91t44jh.js";
|
|
7
|
-
import"../chunk-
|
|
8
|
-
import"../chunk-
|
|
9
|
-
import"../chunk-
|
|
7
|
+
import"../chunk-db4an9td.js";
|
|
8
|
+
import"../chunk-835fssgz.js";
|
|
9
|
+
import"../chunk-gm4swndx.js";
|
|
10
|
+
import"../chunk-rkt41za2.js";
|
|
10
11
|
import"../chunk-v3hxvnrc.js";
|
|
11
12
|
import"../chunk-h8fwx0k7.js";
|
|
12
13
|
import"../chunk-wv4jwhvj.js";
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { type ConnectionOptions } from "mysql2";
|
|
1
2
|
import type { Connection } from "mysql2/promise";
|
|
3
|
+
/** Keep the native handle available so cancellation can destroy an unfinished handshake. */
|
|
4
|
+
export declare function connectMysql(options: ConnectionOptions, signal?: AbortSignal): Promise<Connection>;
|
|
2
5
|
/** @why Disposal must release the socket even when the peer never finishes its TCP half-close. */
|
|
3
6
|
export declare function destroyMysqlConnection(connection: Connection): void;
|
package/dist/mysql/connection.js
CHANGED
package/dist/mysql/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import"../chunk-pfar9cm3.js";
|
|
1
2
|
import {
|
|
2
3
|
withReadScope
|
|
3
4
|
} from "../chunk-4sqvppz7.js";
|
|
@@ -5,9 +6,9 @@ import {
|
|
|
5
6
|
MysqlClient,
|
|
6
7
|
MysqlDatabase,
|
|
7
8
|
openMysql
|
|
8
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-t4hrnaj0.js";
|
|
9
10
|
import"../chunk-m91t44jh.js";
|
|
10
|
-
import"../chunk-
|
|
11
|
+
import"../chunk-db4an9td.js";
|
|
11
12
|
import {
|
|
12
13
|
parseMysqlEnvTarget
|
|
13
14
|
} from "../chunk-qq77x9ek.js";
|
|
@@ -16,9 +17,9 @@ import {
|
|
|
16
17
|
limitedStatement,
|
|
17
18
|
queryLimited
|
|
18
19
|
} from "../chunk-1gyshqd9.js";
|
|
19
|
-
import"../chunk-
|
|
20
|
-
import"../chunk-
|
|
21
|
-
import"../chunk-
|
|
20
|
+
import"../chunk-835fssgz.js";
|
|
21
|
+
import"../chunk-gm4swndx.js";
|
|
22
|
+
import"../chunk-rkt41za2.js";
|
|
22
23
|
import"../chunk-v3hxvnrc.js";
|
|
23
24
|
import"../chunk-h8fwx0k7.js";
|
|
24
25
|
import"../chunk-wv4jwhvj.js";
|
package/dist/mysql/readonly.js
CHANGED
|
@@ -9,8 +9,10 @@ export interface OpenSearchOptions {
|
|
|
9
9
|
node: string;
|
|
10
10
|
auth: OpenSearchAuth;
|
|
11
11
|
requestTimeoutMs?: number;
|
|
12
|
-
/**
|
|
12
|
+
/** Per-route mapping and probe budget; query deadlines remain independent. */
|
|
13
13
|
connectTimeoutMs?: number;
|
|
14
|
+
/** Total acquisition budget; defaults to the per-route budget times the route count. */
|
|
15
|
+
acquireTimeoutMs?: number;
|
|
14
16
|
/** Original TLS identity when a transport maps the socket to localhost. */
|
|
15
17
|
servername?: string;
|
|
16
18
|
}
|
|
@@ -3,8 +3,9 @@ import {
|
|
|
3
3
|
OpenSearchEngine,
|
|
4
4
|
isOpenSearchReadApi,
|
|
5
5
|
openOpenSearch
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import"../chunk-
|
|
6
|
+
} from "../chunk-sbt20n84.js";
|
|
7
|
+
import"../chunk-gm4swndx.js";
|
|
8
|
+
import"../chunk-rkt41za2.js";
|
|
8
9
|
import"../chunk-h8fwx0k7.js";
|
|
9
10
|
import"../chunk-wv4jwhvj.js";
|
|
10
11
|
import"../chunk-631vce5z.js";
|
package/dist/opensearch/index.js
CHANGED
|
@@ -10,8 +10,9 @@ import {
|
|
|
10
10
|
OpenSearchEngine,
|
|
11
11
|
isOpenSearchReadApi,
|
|
12
12
|
openOpenSearch
|
|
13
|
-
} from "../chunk-
|
|
14
|
-
import"../chunk-
|
|
13
|
+
} from "../chunk-sbt20n84.js";
|
|
14
|
+
import"../chunk-gm4swndx.js";
|
|
15
|
+
import"../chunk-rkt41za2.js";
|
|
15
16
|
import"../chunk-h8fwx0k7.js";
|
|
16
17
|
import"../chunk-wv4jwhvj.js";
|
|
17
18
|
import"../chunk-631vce5z.js";
|
package/dist/redis/client.js
CHANGED
|
@@ -4,9 +4,10 @@ import {
|
|
|
4
4
|
RedisConnection,
|
|
5
5
|
openRedis,
|
|
6
6
|
parseRedisInfo
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-f98qrpx1.js";
|
|
8
|
+
import"../chunk-gm4swndx.js";
|
|
8
9
|
import"../chunk-5tbzf9wd.js";
|
|
9
|
-
import"../chunk-
|
|
10
|
+
import"../chunk-rkt41za2.js";
|
|
10
11
|
import"../chunk-h8fwx0k7.js";
|
|
11
12
|
import"../chunk-wv4jwhvj.js";
|
|
12
13
|
import"../chunk-631vce5z.js";
|
package/dist/redis/index.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
collectRedisKeyStats,
|
|
3
|
-
redisGroupedSampleSizes
|
|
4
|
-
} from "../chunk-jr9y0ghr.js";
|
|
5
1
|
import {
|
|
6
2
|
RedisAccess,
|
|
7
3
|
RedisClient,
|
|
8
4
|
RedisConnection,
|
|
9
5
|
openRedis,
|
|
10
6
|
parseRedisInfo
|
|
11
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-f98qrpx1.js";
|
|
8
|
+
import"../chunk-gm4swndx.js";
|
|
9
|
+
import {
|
|
10
|
+
collectRedisKeyStats,
|
|
11
|
+
redisGroupedSampleSizes
|
|
12
|
+
} from "../chunk-jr9y0ghr.js";
|
|
12
13
|
import {
|
|
13
14
|
discoverRedisTopology
|
|
14
15
|
} from "../chunk-5tbzf9wd.js";
|
|
15
|
-
import"../chunk-
|
|
16
|
+
import"../chunk-rkt41za2.js";
|
|
16
17
|
import"../chunk-h8fwx0k7.js";
|
|
17
18
|
import"../chunk-wv4jwhvj.js";
|
|
18
19
|
import"../chunk-631vce5z.js";
|
package/dist/s3/datasource.js
CHANGED
package/dist/s3/index.js
CHANGED
package/package.json
CHANGED
package/dist/chunk-136egyff.js
DELETED