@cratis/chronicle 1.0.2 → 2.1.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.
Files changed (102) hide show
  1. package/ChronicleClient.ts +69 -60
  2. package/ChronicleOptions.ts +5 -6
  3. package/README.md +1 -1
  4. package/connection/ChronicleConnection.ts +37 -17
  5. package/connection/ChronicleConnectionString.spec.ts +227 -0
  6. package/connection/ChronicleConnectionString.ts +289 -35
  7. package/connection/ChronicleServerAddressResolver.spec.ts +41 -0
  8. package/connection/ChronicleServerAddressResolver.ts +33 -0
  9. package/connection/ChronicleSrvResolutionError.ts +13 -0
  10. package/connection/ChronicleSrvResolver.spec.ts +103 -0
  11. package/connection/ChronicleSrvResolver.ts +57 -0
  12. package/connection/ConnectionLifecycle.spec.ts +109 -0
  13. package/connection/ILoadBalancerStrategy.ts +16 -0
  14. package/connection/KernelKeepAlive.spec.ts +175 -0
  15. package/connection/KernelKeepAlive.ts +161 -0
  16. package/connection/LeastConnectionsLoadBalancerStrategy.spec.ts +159 -0
  17. package/connection/LeastConnectionsLoadBalancerStrategy.ts +117 -0
  18. package/connection/LoadBalancerMode.ts +25 -0
  19. package/connection/LoadBalancerStrategyFactory.ts +28 -0
  20. package/connection/RandomLoadBalancerStrategy.spec.ts +50 -0
  21. package/connection/RandomLoadBalancerStrategy.ts +19 -0
  22. package/connection/RoundRobinLoadBalancerStrategy.spec.ts +61 -0
  23. package/connection/RoundRobinLoadBalancerStrategy.ts +29 -0
  24. package/connection/TokenProvider.ts +8 -3
  25. package/connection/formatServerAddress.ts +16 -0
  26. package/dist/ChronicleClient.d.ts +8 -1
  27. package/dist/ChronicleClient.d.ts.map +1 -1
  28. package/dist/ChronicleClient.js +63 -56
  29. package/dist/ChronicleClient.js.map +1 -1
  30. package/dist/ChronicleOptions.d.ts +4 -2
  31. package/dist/ChronicleOptions.d.ts.map +1 -1
  32. package/dist/ChronicleOptions.js +5 -3
  33. package/dist/ChronicleOptions.js.map +1 -1
  34. package/dist/connection/ChronicleConnection.d.ts +4 -5
  35. package/dist/connection/ChronicleConnection.d.ts.map +1 -1
  36. package/dist/connection/ChronicleConnection.js +34 -12
  37. package/dist/connection/ChronicleConnection.js.map +1 -1
  38. package/dist/connection/ChronicleConnectionString.d.ts +77 -3
  39. package/dist/connection/ChronicleConnectionString.d.ts.map +1 -1
  40. package/dist/connection/ChronicleConnectionString.js +250 -32
  41. package/dist/connection/ChronicleConnectionString.js.map +1 -1
  42. package/dist/connection/ChronicleServerAddressResolver.d.ts +23 -0
  43. package/dist/connection/ChronicleServerAddressResolver.d.ts.map +1 -0
  44. package/dist/connection/ChronicleServerAddressResolver.js +32 -0
  45. package/dist/connection/ChronicleServerAddressResolver.js.map +1 -0
  46. package/dist/connection/ChronicleSrvResolutionError.d.ts +8 -0
  47. package/dist/connection/ChronicleSrvResolutionError.d.ts.map +1 -0
  48. package/dist/connection/ChronicleSrvResolutionError.js +13 -0
  49. package/dist/connection/ChronicleSrvResolutionError.js.map +1 -0
  50. package/dist/connection/ChronicleSrvResolver.d.ts +28 -0
  51. package/dist/connection/ChronicleSrvResolver.d.ts.map +1 -0
  52. package/dist/connection/ChronicleSrvResolver.js +51 -0
  53. package/dist/connection/ChronicleSrvResolver.js.map +1 -0
  54. package/dist/connection/ILoadBalancerStrategy.d.ts +13 -0
  55. package/dist/connection/ILoadBalancerStrategy.d.ts.map +1 -0
  56. package/dist/connection/ILoadBalancerStrategy.js +4 -0
  57. package/dist/connection/ILoadBalancerStrategy.js.map +1 -0
  58. package/dist/connection/KernelKeepAlive.d.ts +73 -0
  59. package/dist/connection/KernelKeepAlive.d.ts.map +1 -0
  60. package/dist/connection/KernelKeepAlive.js +115 -0
  61. package/dist/connection/KernelKeepAlive.js.map +1 -0
  62. package/dist/connection/LeastConnectionsLoadBalancerStrategy.d.ts +30 -0
  63. package/dist/connection/LeastConnectionsLoadBalancerStrategy.d.ts.map +1 -0
  64. package/dist/connection/LeastConnectionsLoadBalancerStrategy.js +95 -0
  65. package/dist/connection/LeastConnectionsLoadBalancerStrategy.js.map +1 -0
  66. package/dist/connection/LoadBalancerMode.d.ts +21 -0
  67. package/dist/connection/LoadBalancerMode.d.ts.map +1 -0
  68. package/dist/connection/LoadBalancerMode.js +24 -0
  69. package/dist/connection/LoadBalancerMode.js.map +1 -0
  70. package/dist/connection/LoadBalancerStrategyFactory.d.ts +11 -0
  71. package/dist/connection/LoadBalancerStrategyFactory.d.ts.map +1 -0
  72. package/dist/connection/LoadBalancerStrategyFactory.js +26 -0
  73. package/dist/connection/LoadBalancerStrategyFactory.js.map +1 -0
  74. package/dist/connection/RandomLoadBalancerStrategy.d.ts +9 -0
  75. package/dist/connection/RandomLoadBalancerStrategy.d.ts.map +1 -0
  76. package/dist/connection/RandomLoadBalancerStrategy.js +15 -0
  77. package/dist/connection/RandomLoadBalancerStrategy.js.map +1 -0
  78. package/dist/connection/RoundRobinLoadBalancerStrategy.d.ts +12 -0
  79. package/dist/connection/RoundRobinLoadBalancerStrategy.d.ts.map +1 -0
  80. package/dist/connection/RoundRobinLoadBalancerStrategy.js +22 -0
  81. package/dist/connection/RoundRobinLoadBalancerStrategy.js.map +1 -0
  82. package/dist/connection/TokenProvider.d.ts +2 -1
  83. package/dist/connection/TokenProvider.d.ts.map +1 -1
  84. package/dist/connection/TokenProvider.js +9 -3
  85. package/dist/connection/TokenProvider.js.map +1 -1
  86. package/dist/connection/formatServerAddress.d.ts +10 -0
  87. package/dist/connection/formatServerAddress.d.ts.map +1 -0
  88. package/dist/connection/formatServerAddress.js +14 -0
  89. package/dist/connection/formatServerAddress.js.map +1 -0
  90. package/dist/reactors/Reactors.d.ts +13 -0
  91. package/dist/reactors/Reactors.d.ts.map +1 -1
  92. package/dist/reactors/Reactors.js +42 -4
  93. package/dist/reactors/Reactors.js.map +1 -1
  94. package/dist/reducers/Reducers.d.ts +14 -0
  95. package/dist/reducers/Reducers.d.ts.map +1 -1
  96. package/dist/reducers/Reducers.js +43 -8
  97. package/dist/reducers/Reducers.js.map +1 -1
  98. package/dist/tsconfig.tsbuildinfo +1 -1
  99. package/package.json +8 -5
  100. package/reactors/Reactors.ts +53 -4
  101. package/reducers/Reducers.ts +55 -8
  102. package/vitest.config.ts +12 -0
@@ -1,6 +1,10 @@
1
1
  // Copyright (c) Cratis. All rights reserved.
2
2
  // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
3
  import * as grpc from '@grpc/grpc-js';
4
+ import { formatServerAddress } from './formatServerAddress';
5
+ import { LoadBalancerMode } from './LoadBalancerMode';
6
+ const DEFAULT_PORT = 35000;
7
+ const SRV_SCHEME = 'chronicle+srv';
4
8
  /**
5
9
  * Authentication mode for Chronicle connection.
6
10
  */
@@ -9,38 +13,115 @@ export var AuthenticationMode;
9
13
  AuthenticationMode["ClientCredentials"] = "ClientCredentials";
10
14
  AuthenticationMode["ApiKey"] = "ApiKey";
11
15
  })(AuthenticationMode || (AuthenticationMode = {}));
16
+ /**
17
+ * Splits a `host1:port1,host2:port2` host list on top-level commas, leaving commas that
18
+ * appear inside IPv6 bracket literals (`[::1]:35000`) intact.
19
+ */
20
+ function splitHostList(value) {
21
+ const entries = [];
22
+ let depth = 0;
23
+ let current = '';
24
+ for (const character of value) {
25
+ if (character === '[') {
26
+ depth++;
27
+ }
28
+ else if (character === ']') {
29
+ depth--;
30
+ }
31
+ if (character === ',' && depth === 0) {
32
+ entries.push(current);
33
+ current = '';
34
+ continue;
35
+ }
36
+ current += character;
37
+ }
38
+ if (current.length > 0) {
39
+ entries.push(current);
40
+ }
41
+ return entries;
42
+ }
43
+ /**
44
+ * Parses a single `host:port` or `[ipv6]:port` entry, defaulting the port when omitted.
45
+ */
46
+ function parseHostAndPort(entry) {
47
+ const trimmed = entry.trim();
48
+ let host;
49
+ let portPart;
50
+ if (trimmed.startsWith('[')) {
51
+ const closingIndex = trimmed.indexOf(']');
52
+ if (closingIndex === -1) {
53
+ throw new Error(`Invalid server address: ${trimmed}`);
54
+ }
55
+ host = trimmed.slice(1, closingIndex);
56
+ portPart = trimmed.slice(closingIndex + 1).replace(/^:/, '');
57
+ }
58
+ else {
59
+ const colonIndex = trimmed.lastIndexOf(':');
60
+ host = colonIndex === -1 ? trimmed : trimmed.slice(0, colonIndex);
61
+ portPart = colonIndex === -1 ? '' : trimmed.slice(colonIndex + 1);
62
+ }
63
+ if (host.length === 0) {
64
+ throw new Error(`Invalid server address: ${trimmed}`);
65
+ }
66
+ if (portPart.length === 0) {
67
+ return { host, port: DEFAULT_PORT };
68
+ }
69
+ const port = Number(portPart);
70
+ if (!Number.isInteger(port)) {
71
+ throw new Error(`Invalid server address: ${trimmed}`);
72
+ }
73
+ return { host, port };
74
+ }
12
75
  /**
13
76
  * Builder for constructing Chronicle connection strings.
14
77
  */
15
78
  export class ChronicleConnectionStringBuilder {
16
- static _defaultPort = 35000;
17
- static _hostKey = 'Host';
18
- static _portKey = 'Port';
79
+ static _defaultPort = DEFAULT_PORT;
19
80
  static _usernameKey = 'Username';
20
81
  static _passwordKey = 'Password';
21
82
  static _schemeKey = 'Scheme';
22
83
  static _apiKeyKey = 'apiKey';
23
84
  static _disableTlsKey = 'disableTls';
85
+ static _skipTlsValidationKey = 'skipTlsValidation';
24
86
  static _certificatePathKey = 'certificatePath';
25
87
  static _certificatePasswordKey = 'certificatePassword';
88
+ static _loadBalancerKey = 'loadBalancer';
89
+ static _srvNameServerKey = 'srvNameServer';
26
90
  _properties = new Map();
91
+ _hosts = [];
27
92
  constructor(connectionString) {
28
93
  if (connectionString) {
29
94
  this.parseConnectionString(connectionString);
30
95
  }
31
96
  }
97
+ get hosts() {
98
+ return this._hosts.length > 0 ? this._hosts : [{ host: 'localhost', port: ChronicleConnectionStringBuilder._defaultPort }];
99
+ }
100
+ set hosts(value) {
101
+ this._hosts = value;
102
+ }
103
+ /**
104
+ * Convenience accessor for the first host in {@link hosts}. Setting it collapses the
105
+ * configuration to that single host, discarding any others previously set via
106
+ * {@link hosts} - the same "single server" reset a plain host/port connection string
107
+ * implies.
108
+ */
32
109
  get host() {
33
- return this._properties.get(ChronicleConnectionStringBuilder._hostKey) || 'localhost';
110
+ return this.hosts[0].host;
34
111
  }
35
112
  set host(value) {
36
- this._properties.set(ChronicleConnectionStringBuilder._hostKey, value);
113
+ this._hosts = [{ host: value, port: this.hosts[0].port }];
37
114
  }
115
+ /**
116
+ * Convenience accessor for the first host's port in {@link hosts}. Setting it collapses
117
+ * the configuration to that single host, discarding any others previously set via
118
+ * {@link hosts}.
119
+ */
38
120
  get port() {
39
- const port = this._properties.get(ChronicleConnectionStringBuilder._portKey);
40
- return port ? parseInt(port, 10) : ChronicleConnectionStringBuilder._defaultPort;
121
+ return this.hosts[0].port;
41
122
  }
42
123
  set port(value) {
43
- this._properties.set(ChronicleConnectionStringBuilder._portKey, value.toString());
124
+ this._hosts = [{ host: this.hosts[0].host, port: value }];
44
125
  }
45
126
  get username() {
46
127
  return this._properties.get(ChronicleConnectionStringBuilder._usernameKey);
@@ -68,6 +149,13 @@ export class ChronicleConnectionStringBuilder {
68
149
  set scheme(value) {
69
150
  this._properties.set(ChronicleConnectionStringBuilder._schemeKey, value);
70
151
  }
152
+ /**
153
+ * Whether the connection string uses the DNS SRV lookup scheme (`chronicle+srv://`).
154
+ * Compared case-insensitively, matching {@link scheme}'s own parsing.
155
+ */
156
+ get isSrv() {
157
+ return this.scheme.toLowerCase() === SRV_SCHEME;
158
+ }
71
159
  get authenticationMode() {
72
160
  const hasClientCredentials = !!this.username && !!this.password;
73
161
  const hasApiKey = !!this.apiKey;
@@ -98,6 +186,19 @@ export class ChronicleConnectionStringBuilder {
98
186
  set disableTls(value) {
99
187
  this._properties.set(ChronicleConnectionStringBuilder._disableTlsKey, value.toString());
100
188
  }
189
+ /**
190
+ * Whether TLS certificate validation is skipped for the gRPC channel and OAuth token
191
+ * requests. Distinct from {@link disableTls}, which controls whether TLS is used at
192
+ * all. Defaults to `true` - set to `false` to require full certificate validation
193
+ * whenever TLS is on.
194
+ */
195
+ get skipTlsValidation() {
196
+ const raw = this._properties.get(ChronicleConnectionStringBuilder._skipTlsValidationKey);
197
+ return raw === undefined || raw === 'true';
198
+ }
199
+ set skipTlsValidation(value) {
200
+ this._properties.set(ChronicleConnectionStringBuilder._skipTlsValidationKey, value.toString());
201
+ }
101
202
  get certificatePath() {
102
203
  return this._properties.get(ChronicleConnectionStringBuilder._certificatePathKey);
103
204
  }
@@ -118,7 +219,44 @@ export class ChronicleConnectionStringBuilder {
118
219
  }
119
220
  this._properties.delete(ChronicleConnectionStringBuilder._certificatePasswordKey);
120
221
  }
222
+ /**
223
+ * The strategy used to select one address from {@link hosts} (or the addresses
224
+ * resolved from a `chronicle+srv://` host) on every connect/reconnect attempt.
225
+ * Defaults to {@link LoadBalancerMode.LeastConnections}.
226
+ */
227
+ get loadBalancer() {
228
+ const raw = this._properties.get(ChronicleConnectionStringBuilder._loadBalancerKey);
229
+ if (!raw) {
230
+ return LoadBalancerMode.LeastConnections;
231
+ }
232
+ const knownModes = Object.values(LoadBalancerMode);
233
+ if (!knownModes.includes(raw)) {
234
+ throw new Error(`Unknown loadBalancer strategy '${raw}'. Expected one of: ${knownModes.join(', ')}`);
235
+ }
236
+ return raw;
237
+ }
238
+ set loadBalancer(value) {
239
+ this._properties.set(ChronicleConnectionStringBuilder._loadBalancerKey, value);
240
+ }
241
+ /**
242
+ * The `host[:port]` DNS name server used to resolve `chronicle+srv://` SRV records.
243
+ * Defaults to port 53 when no port is given. Undefined uses the system default
244
+ * resolver.
245
+ */
246
+ get srvNameServer() {
247
+ return this._properties.get(ChronicleConnectionStringBuilder._srvNameServerKey);
248
+ }
249
+ set srvNameServer(value) {
250
+ if (value) {
251
+ this._properties.set(ChronicleConnectionStringBuilder._srvNameServerKey, value);
252
+ return;
253
+ }
254
+ this._properties.delete(ChronicleConnectionStringBuilder._srvNameServerKey);
255
+ }
121
256
  build() {
257
+ if (this.isSrv && this.hosts.length > 1) {
258
+ throw new Error(`${SRV_SCHEME} connection strings support only a single host, found ${this.hosts.length}`);
259
+ }
122
260
  let result = `${this.scheme}://`;
123
261
  if (this.username) {
124
262
  result += this.username;
@@ -127,8 +265,7 @@ export class ChronicleConnectionStringBuilder {
127
265
  }
128
266
  result += '@';
129
267
  }
130
- result += this.host;
131
- result += `:${this.port}`;
268
+ result += this.hosts.map(formatServerAddress).join(',');
132
269
  const queryParameters = [];
133
270
  if (this.apiKey) {
134
271
  queryParameters.push(`apiKey=${encodeURIComponent(this.apiKey)}`);
@@ -136,22 +273,32 @@ export class ChronicleConnectionStringBuilder {
136
273
  if (this.disableTls) {
137
274
  queryParameters.push('disableTls=true');
138
275
  }
276
+ if (!this.skipTlsValidation) {
277
+ queryParameters.push('skipTlsValidation=false');
278
+ }
139
279
  if (this.certificatePath) {
140
280
  queryParameters.push(`certificatePath=${encodeURIComponent(this.certificatePath)}`);
141
281
  }
142
282
  if (this.certificatePassword) {
143
283
  queryParameters.push(`certificatePassword=${encodeURIComponent(this.certificatePassword)}`);
144
284
  }
285
+ if (this._properties.has(ChronicleConnectionStringBuilder._loadBalancerKey)) {
286
+ queryParameters.push(`loadBalancer=${encodeURIComponent(this.loadBalancer)}`);
287
+ }
288
+ if (this.srvNameServer) {
289
+ queryParameters.push(`srvNameServer=${encodeURIComponent(this.srvNameServer)}`);
290
+ }
145
291
  for (const [key, value] of this._properties) {
146
- if (key !== ChronicleConnectionStringBuilder._hostKey &&
147
- key !== ChronicleConnectionStringBuilder._portKey &&
148
- key !== ChronicleConnectionStringBuilder._usernameKey &&
292
+ if (key !== ChronicleConnectionStringBuilder._usernameKey &&
149
293
  key !== ChronicleConnectionStringBuilder._passwordKey &&
150
294
  key !== ChronicleConnectionStringBuilder._schemeKey &&
151
295
  key !== ChronicleConnectionStringBuilder._apiKeyKey &&
152
296
  key !== ChronicleConnectionStringBuilder._disableTlsKey &&
297
+ key !== ChronicleConnectionStringBuilder._skipTlsValidationKey &&
153
298
  key !== ChronicleConnectionStringBuilder._certificatePathKey &&
154
- key !== ChronicleConnectionStringBuilder._certificatePasswordKey) {
299
+ key !== ChronicleConnectionStringBuilder._certificatePasswordKey &&
300
+ key !== ChronicleConnectionStringBuilder._loadBalancerKey &&
301
+ key !== ChronicleConnectionStringBuilder._srvNameServerKey) {
155
302
  queryParameters.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
156
303
  }
157
304
  }
@@ -161,26 +308,47 @@ export class ChronicleConnectionStringBuilder {
161
308
  return result;
162
309
  }
163
310
  parseConnectionString(connectionString) {
164
- if (connectionString.startsWith('chronicle://') ||
165
- connectionString.startsWith('chronicle+srv://')) {
311
+ const lowerCased = connectionString.toLowerCase();
312
+ if (lowerCased.startsWith('chronicle://') || lowerCased.startsWith(`${SRV_SCHEME}://`)) {
166
313
  this.parseUrl(connectionString);
167
314
  }
168
315
  }
169
316
  parseUrl(value) {
170
317
  try {
171
- const parsed = new URL(value);
172
- this.scheme = parsed.protocol.replace(':', '');
173
- this.host = parsed.hostname;
174
- if (parsed.port) {
175
- this.port = parseInt(parsed.port, 10);
318
+ const schemeSeparatorIndex = value.indexOf('://');
319
+ const scheme = value.slice(0, schemeSeparatorIndex);
320
+ this.scheme = scheme;
321
+ const rest = value.slice(schemeSeparatorIndex + 3);
322
+ // The authority (userinfo + hosts) ends at the first '/' or '?'; parsing tolerates
323
+ // an optional trailing slash immediately before the query string this way.
324
+ const pathIndex = [rest.indexOf('/'), rest.indexOf('?')]
325
+ .filter(index => index >= 0)
326
+ .sort((first, second) => first - second)[0];
327
+ const authority = pathIndex === undefined ? rest : rest.slice(0, pathIndex);
328
+ let query = '';
329
+ if (pathIndex !== undefined) {
330
+ const queryIndex = rest.indexOf('?', pathIndex);
331
+ query = queryIndex === -1 ? '' : rest.slice(queryIndex + 1);
176
332
  }
177
- if (parsed.username) {
178
- this.username = decodeURIComponent(parsed.username);
179
- if (parsed.password) {
180
- this.password = decodeURIComponent(parsed.password);
333
+ // The userinfo separator is the LAST '@' in the authority, so a host portion never
334
+ // legitimately containing '@' can't be confused for one.
335
+ const authoritySeparatorIndex = authority.lastIndexOf('@');
336
+ let hostList = authority;
337
+ if (authoritySeparatorIndex >= 0) {
338
+ const userInfo = authority.slice(0, authoritySeparatorIndex);
339
+ hostList = authority.slice(authoritySeparatorIndex + 1);
340
+ const parts = userInfo.split(':');
341
+ this.username = decodeURIComponent(parts[0]);
342
+ if (parts.length > 1) {
343
+ this.password = decodeURIComponent(parts[1]);
181
344
  }
182
345
  }
183
- for (const [key, queryValue] of new URLSearchParams(parsed.search)) {
346
+ const hosts = splitHostList(hostList).map(parseHostAndPort);
347
+ if (this.isSrv && hosts.length > 1) {
348
+ throw new Error(`${SRV_SCHEME} connection strings support only a single host, found ${hosts.length}`);
349
+ }
350
+ this.hosts = hosts;
351
+ for (const [key, queryValue] of new URLSearchParams(query)) {
184
352
  this._properties.set(key, decodeURIComponent(queryValue));
185
353
  }
186
354
  }
@@ -196,18 +364,41 @@ export class ChronicleConnectionString {
196
364
  static DEVELOPMENT_CLIENT = 'chronicle-dev-client';
197
365
  static DEVELOPMENT_CLIENT_SECRET = 'chronicle-dev-secret';
198
366
  static Default = new ChronicleConnectionString('chronicle://localhost:35000');
367
+ // skipTlsValidation defaults to true, so no explicit query parameter is needed here for
368
+ // this to connect to the Kernel's self-signed development certificate.
199
369
  static Development = new ChronicleConnectionString(`chronicle://${ChronicleConnectionString.DEVELOPMENT_CLIENT}:${ChronicleConnectionString.DEVELOPMENT_CLIENT_SECRET}@localhost:35000`);
200
370
  _builder;
201
- _serverAddress;
371
+ _serverAddresses;
202
372
  constructor(connectionString) {
203
373
  this._builder = new ChronicleConnectionStringBuilder(connectionString);
204
- this._serverAddress = {
205
- host: this._builder.host,
206
- port: this._builder.port
207
- };
374
+ this._serverAddresses = this._builder.hosts;
208
375
  }
376
+ /**
377
+ * The connection string's scheme, either `chronicle` or `chronicle+srv`.
378
+ */
379
+ get scheme() {
380
+ return this._builder.scheme;
381
+ }
382
+ /**
383
+ * Whether the connection string uses the DNS SRV lookup scheme (`chronicle+srv://`).
384
+ */
385
+ get isSrv() {
386
+ return this._builder.isSrv;
387
+ }
388
+ /**
389
+ * Convenience accessor for the first entry in {@link serverAddresses}, for callers
390
+ * that only ever expect a single server address.
391
+ */
209
392
  get serverAddress() {
210
- return this._serverAddress;
393
+ return this._serverAddresses[0];
394
+ }
395
+ /**
396
+ * All server addresses parsed from a multi-host `chronicle://` connection string.
397
+ * For `chronicle+srv://` connection strings, this holds the single SRV lookup host,
398
+ * not the resolved addresses - resolve those via {@link ChronicleServerAddressResolver}.
399
+ */
400
+ get serverAddresses() {
401
+ return this._serverAddresses;
211
402
  }
212
403
  get username() {
213
404
  return this._builder.username;
@@ -224,12 +415,31 @@ export class ChronicleConnectionString {
224
415
  get disableTls() {
225
416
  return this._builder.disableTls;
226
417
  }
418
+ /**
419
+ * Whether TLS certificate validation is skipped. See
420
+ * {@link ChronicleConnectionStringBuilder.skipTlsValidation}.
421
+ */
422
+ get skipTlsValidation() {
423
+ return this._builder.skipTlsValidation;
424
+ }
227
425
  get certificatePath() {
228
426
  return this._builder.certificatePath;
229
427
  }
230
428
  get certificatePassword() {
231
429
  return this._builder.certificatePassword;
232
430
  }
431
+ /**
432
+ * The strategy used to select one server address on every connect/reconnect attempt.
433
+ */
434
+ get loadBalancer() {
435
+ return this._builder.loadBalancer;
436
+ }
437
+ /**
438
+ * The `host[:port]` DNS name server used to resolve `chronicle+srv://` SRV records.
439
+ */
440
+ get srvNameServer() {
441
+ return this._builder.srvNameServer;
442
+ }
233
443
  withCredentials(username, password) {
234
444
  const builder = new ChronicleConnectionStringBuilder(this.toString());
235
445
  builder.username = username;
@@ -245,6 +455,14 @@ export class ChronicleConnectionString {
245
455
  if (this.disableTls) {
246
456
  return grpc.credentials.createInsecure();
247
457
  }
458
+ if (this.skipTlsValidation) {
459
+ // Chronicle generates a self-signed certificate in development, and skipTlsValidation
460
+ // defaults to true so this works without extra configuration. grpc-js has no
461
+ // per-error hook to accept only self-signed/untrusted-root chains the way a
462
+ // finer-grained validator would, so skipTlsValidation bypasses chain validation
463
+ // entirely. Set skipTlsValidation=false for a server with a verifiable certificate.
464
+ return grpc.credentials.createSsl(null, null, null, { rejectUnauthorized: false });
465
+ }
248
466
  return grpc.credentials.createSsl();
249
467
  }
250
468
  toString() {
@@ -1 +1 @@
1
- {"version":3,"file":"ChronicleConnectionString.js","sourceRoot":"","sources":["../../connection/ChronicleConnectionString.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChronicleConnectionString.js","sourceRoot":"","sources":["../../connection/ChronicleConnectionString.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { ChronicleConnectionString, ChronicleServerAddress } from './ChronicleConnectionString';
2
+ import { ChronicleSrvResolver } from './ChronicleSrvResolver';
3
+ /**
4
+ * Resolves the effective list of Chronicle server addresses for a connection string.
5
+ * `chronicle+srv://` connection strings are resolved via DNS SRV lookup on every call;
6
+ * plain `chronicle://` connection strings pass their parsed host list through unchanged
7
+ * and never touch DNS.
8
+ */
9
+ export declare class ChronicleServerAddressResolver {
10
+ private readonly _srvResolver;
11
+ /**
12
+ * Initializes a new instance of {@link ChronicleServerAddressResolver}.
13
+ * @param _srvResolver - The SRV resolver used for `chronicle+srv://` connection strings.
14
+ */
15
+ constructor(_srvResolver?: ChronicleSrvResolver);
16
+ /**
17
+ * Resolves the server addresses for a connection string.
18
+ * @param connectionString - The connection string to resolve addresses for.
19
+ * @returns The resolved addresses.
20
+ */
21
+ resolve(connectionString: ChronicleConnectionString): Promise<ChronicleServerAddress[]>;
22
+ }
23
+ //# sourceMappingURL=ChronicleServerAddressResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChronicleServerAddressResolver.d.ts","sourceRoot":"","sources":["../../connection/ChronicleServerAddressResolver.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrG,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;;;;GAKG;AACH,qBAAa,8BAA8B;IAK3B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAJzC;;;OAGG;gBAC0B,YAAY,GAAE,oBAAiD;IAE5F;;;;OAIG;IACG,OAAO,CAAC,gBAAgB,EAAE,yBAAyB,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC;CAQhG"}
@@ -0,0 +1,32 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+ import { ChronicleSrvResolver } from './ChronicleSrvResolver';
4
+ /**
5
+ * Resolves the effective list of Chronicle server addresses for a connection string.
6
+ * `chronicle+srv://` connection strings are resolved via DNS SRV lookup on every call;
7
+ * plain `chronicle://` connection strings pass their parsed host list through unchanged
8
+ * and never touch DNS.
9
+ */
10
+ export class ChronicleServerAddressResolver {
11
+ _srvResolver;
12
+ /**
13
+ * Initializes a new instance of {@link ChronicleServerAddressResolver}.
14
+ * @param _srvResolver - The SRV resolver used for `chronicle+srv://` connection strings.
15
+ */
16
+ constructor(_srvResolver = new ChronicleSrvResolver()) {
17
+ this._srvResolver = _srvResolver;
18
+ }
19
+ /**
20
+ * Resolves the server addresses for a connection string.
21
+ * @param connectionString - The connection string to resolve addresses for.
22
+ * @returns The resolved addresses.
23
+ */
24
+ async resolve(connectionString) {
25
+ if (!connectionString.isSrv) {
26
+ return connectionString.serverAddresses;
27
+ }
28
+ const [srvHost] = connectionString.serverAddresses;
29
+ return this._srvResolver.resolve(srvHost.host, connectionString.srvNameServer);
30
+ }
31
+ }
32
+ //# sourceMappingURL=ChronicleServerAddressResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChronicleServerAddressResolver.js","sourceRoot":"","sources":["../../connection/ChronicleServerAddressResolver.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,qGAAqG;AAGrG,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,OAAO,8BAA8B;IAKV;IAJ7B;;;OAGG;IACH,YAA6B,eAAqC,IAAI,oBAAoB,EAAE;QAA/D,iBAAY,GAAZ,YAAY,CAAmD;IAAG,CAAC;IAEhG;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,gBAA2C;QACrD,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;YAC1B,OAAO,gBAAgB,CAAC,eAAe,CAAC;QAC5C,CAAC;QAED,MAAM,CAAC,OAAO,CAAC,GAAG,gBAAgB,CAAC,eAAe,CAAC;QACnD,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,gBAAgB,CAAC,aAAa,CAAC,CAAC;IACnF,CAAC;CACJ"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Thrown when a `chronicle+srv://` connection string's DNS zone publishes no SRV records
3
+ * for the queried name.
4
+ */
5
+ export declare class ChronicleSrvResolutionError extends Error {
6
+ constructor(name: string);
7
+ }
8
+ //# sourceMappingURL=ChronicleSrvResolutionError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChronicleSrvResolutionError.d.ts","sourceRoot":"","sources":["../../connection/ChronicleSrvResolutionError.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;gBACtC,IAAI,EAAE,MAAM;CAI3B"}
@@ -0,0 +1,13 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+ /**
4
+ * Thrown when a `chronicle+srv://` connection string's DNS zone publishes no SRV records
5
+ * for the queried name.
6
+ */
7
+ export class ChronicleSrvResolutionError extends Error {
8
+ constructor(name) {
9
+ super(`No SRV records found for '${name}'. Verify the DNS zone publishes _chronicle._tcp SRV records for this host.`);
10
+ this.name = 'ChronicleSrvResolutionError';
11
+ }
12
+ }
13
+ //# sourceMappingURL=ChronicleSrvResolutionError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChronicleSrvResolutionError.js","sourceRoot":"","sources":["../../connection/ChronicleSrvResolutionError.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,qGAAqG;AAErG;;;GAGG;AACH,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IAClD,YAAY,IAAY;QACpB,KAAK,CAAC,6BAA6B,IAAI,6EAA6E,CAAC,CAAC;QACtH,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC9C,CAAC;CACJ"}
@@ -0,0 +1,28 @@
1
+ import { Resolver } from 'dns/promises';
2
+ import type { ChronicleServerAddress } from './ChronicleConnectionString';
3
+ /**
4
+ * Resolves Chronicle server addresses from DNS SRV records for `chronicle+srv://`
5
+ * connection strings, querying `_chronicle._tcp.<host>` the same way the .NET reference
6
+ * client does. Every call performs a fresh DNS query - results are never cached here, so
7
+ * that reconnects always pick up membership changes.
8
+ */
9
+ export declare class ChronicleSrvResolver {
10
+ private readonly _createResolver;
11
+ /**
12
+ * Initializes a new instance of {@link ChronicleSrvResolver}.
13
+ * @param _createResolver - Factory creating the `dns.promises.Resolver` used for each
14
+ * resolution. Overridable for testing; defaults to a fresh `Resolver` per call.
15
+ */
16
+ constructor(_createResolver?: () => Resolver);
17
+ /**
18
+ * Resolves the SRV records for a `chronicle+srv://` host.
19
+ * @param host - The host portion of the `chronicle+srv://` connection string.
20
+ * @param nameServer - Optional `host[:port]` DNS name server to query instead of the
21
+ * system default. Defaults to port 53 when no port is given.
22
+ * @returns The resolved addresses, sorted ascending by priority and then descending by
23
+ * weight, per RFC 2782.
24
+ */
25
+ resolve(host: string, nameServer?: string): Promise<ChronicleServerAddress[]>;
26
+ private withDefaultPort;
27
+ }
28
+ //# sourceMappingURL=ChronicleSrvResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChronicleSrvResolver.d.ts","sourceRoot":"","sources":["../../connection/ChronicleSrvResolver.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAK1E;;;;;GAKG;AACH,qBAAa,oBAAoB;IAMjB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAL5C;;;;OAIG;gBAC0B,eAAe,GAAE,MAAM,QAA+B;IAEnF;;;;;;;OAOG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC;IAqBnF,OAAO,CAAC,eAAe;CAI1B"}
@@ -0,0 +1,51 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+ import { Resolver } from 'dns/promises';
4
+ import { ChronicleSrvResolutionError } from './ChronicleSrvResolutionError';
5
+ const DEFAULT_DNS_PORT = 53;
6
+ /**
7
+ * Resolves Chronicle server addresses from DNS SRV records for `chronicle+srv://`
8
+ * connection strings, querying `_chronicle._tcp.<host>` the same way the .NET reference
9
+ * client does. Every call performs a fresh DNS query - results are never cached here, so
10
+ * that reconnects always pick up membership changes.
11
+ */
12
+ export class ChronicleSrvResolver {
13
+ _createResolver;
14
+ /**
15
+ * Initializes a new instance of {@link ChronicleSrvResolver}.
16
+ * @param _createResolver - Factory creating the `dns.promises.Resolver` used for each
17
+ * resolution. Overridable for testing; defaults to a fresh `Resolver` per call.
18
+ */
19
+ constructor(_createResolver = () => new Resolver()) {
20
+ this._createResolver = _createResolver;
21
+ }
22
+ /**
23
+ * Resolves the SRV records for a `chronicle+srv://` host.
24
+ * @param host - The host portion of the `chronicle+srv://` connection string.
25
+ * @param nameServer - Optional `host[:port]` DNS name server to query instead of the
26
+ * system default. Defaults to port 53 when no port is given.
27
+ * @returns The resolved addresses, sorted ascending by priority and then descending by
28
+ * weight, per RFC 2782.
29
+ */
30
+ async resolve(host, nameServer) {
31
+ const resolver = this._createResolver();
32
+ if (nameServer) {
33
+ resolver.setServers([this.withDefaultPort(nameServer)]);
34
+ }
35
+ const name = `_chronicle._tcp.${host}`;
36
+ const records = await resolver.resolveSrv(name);
37
+ if (records.length === 0) {
38
+ throw new ChronicleSrvResolutionError(name);
39
+ }
40
+ return records
41
+ .slice()
42
+ .sort((first, second) => first.priority - second.priority || second.weight - first.weight)
43
+ // SRV targets are frequently returned as FQDNs with a trailing root '.'.
44
+ .map(record => ({ host: record.name.replace(/\.$/, ''), port: record.port }));
45
+ }
46
+ withDefaultPort(nameServer) {
47
+ const colonIndex = nameServer.lastIndexOf(':');
48
+ return colonIndex === -1 ? `${nameServer}:${DEFAULT_DNS_PORT}` : nameServer;
49
+ }
50
+ }
51
+ //# sourceMappingURL=ChronicleSrvResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChronicleSrvResolver.js","sourceRoot":"","sources":["../../connection/ChronicleSrvResolver.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,qGAAqG;AAErG,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAE5E,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAE5B;;;;;GAKG;AACH,MAAM,OAAO,oBAAoB;IAMA;IAL7B;;;;OAIG;IACH,YAA6B,kBAAkC,GAAG,EAAE,CAAC,IAAI,QAAQ,EAAE;QAAtD,oBAAe,GAAf,eAAe,CAAuC;IAAG,CAAC;IAEvF;;;;;;;OAOG;IACH,KAAK,CAAC,OAAO,CAAC,IAAY,EAAE,UAAmB;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QAExC,IAAI,UAAU,EAAE,CAAC;YACb,QAAQ,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,IAAI,GAAG,mBAAmB,IAAI,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAEhD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,2BAA2B,CAAC,IAAI,CAAC,CAAC;QAChD,CAAC;QAED,OAAO,OAAO;aACT,KAAK,EAAE;aACP,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;YAC1F,yEAAyE;aACxE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACtF,CAAC;IAEO,eAAe,CAAC,UAAkB;QACtC,MAAM,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAC/C,OAAO,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,gBAAgB,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;IAChF,CAAC;CACJ"}