@milaboratories/pl-client 2.16.12 → 2.16.14

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 (74) hide show
  1. package/dist/__external/.pnpm/{@rollup_plugin-typescript@12.1.4_rollup@4.52.4_tslib@2.8.1_typescript@5.6.3 → @rollup_plugin-typescript@12.3.0_rollup@4.52.4_tslib@2.8.1_typescript@5.6.3}/__external/tslib/tslib.es6.cjs.map +1 -1
  2. package/dist/__external/.pnpm/{@rollup_plugin-typescript@12.1.4_rollup@4.52.4_tslib@2.8.1_typescript@5.6.3 → @rollup_plugin-typescript@12.3.0_rollup@4.52.4_tslib@2.8.1_typescript@5.6.3}/__external/tslib/tslib.es6.js.map +1 -1
  3. package/dist/core/client.cjs +31 -16
  4. package/dist/core/client.cjs.map +1 -1
  5. package/dist/core/client.d.ts +3 -2
  6. package/dist/core/client.d.ts.map +1 -1
  7. package/dist/core/client.js +31 -16
  8. package/dist/core/client.js.map +1 -1
  9. package/dist/core/default_client.cjs +1 -1
  10. package/dist/core/default_client.cjs.map +1 -1
  11. package/dist/core/default_client.js +1 -1
  12. package/dist/core/default_client.js.map +1 -1
  13. package/dist/core/driver.cjs +1 -1
  14. package/dist/core/driver.cjs.map +1 -1
  15. package/dist/core/driver.js +1 -1
  16. package/dist/core/driver.js.map +1 -1
  17. package/dist/core/errors.cjs +15 -4
  18. package/dist/core/errors.cjs.map +1 -1
  19. package/dist/core/errors.d.ts.map +1 -1
  20. package/dist/core/errors.js +15 -4
  21. package/dist/core/errors.js.map +1 -1
  22. package/dist/core/ll_client.cjs +61 -21
  23. package/dist/core/ll_client.cjs.map +1 -1
  24. package/dist/core/ll_client.d.ts +12 -3
  25. package/dist/core/ll_client.d.ts.map +1 -1
  26. package/dist/core/ll_client.js +62 -22
  27. package/dist/core/ll_client.js.map +1 -1
  28. package/dist/core/transaction.cjs +1 -1
  29. package/dist/core/transaction.js +1 -1
  30. package/dist/core/unauth_client.cjs +6 -2
  31. package/dist/core/unauth_client.cjs.map +1 -1
  32. package/dist/core/unauth_client.d.ts +2 -1
  33. package/dist/core/unauth_client.d.ts.map +1 -1
  34. package/dist/core/unauth_client.js +6 -2
  35. package/dist/core/unauth_client.js.map +1 -1
  36. package/dist/core/websocket_stream.cjs +147 -129
  37. package/dist/core/websocket_stream.cjs.map +1 -1
  38. package/dist/core/websocket_stream.d.ts +29 -22
  39. package/dist/core/websocket_stream.d.ts.map +1 -1
  40. package/dist/core/websocket_stream.js +148 -130
  41. package/dist/core/websocket_stream.js.map +1 -1
  42. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.cjs +136 -0
  43. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.cjs.map +1 -1
  44. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts +75 -1
  45. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts.map +1 -1
  46. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.js +135 -1
  47. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.js.map +1 -1
  48. package/dist/proto-rest/index.cjs +16 -2
  49. package/dist/proto-rest/index.cjs.map +1 -1
  50. package/dist/proto-rest/index.d.ts.map +1 -1
  51. package/dist/proto-rest/index.js +16 -2
  52. package/dist/proto-rest/index.js.map +1 -1
  53. package/dist/test/test_config.cjs +13 -3
  54. package/dist/test/test_config.cjs.map +1 -1
  55. package/dist/test/test_config.d.ts +4 -0
  56. package/dist/test/test_config.d.ts.map +1 -1
  57. package/dist/test/test_config.js +12 -4
  58. package/dist/test/test_config.js.map +1 -1
  59. package/package.json +6 -6
  60. package/src/core/client.ts +40 -21
  61. package/src/core/default_client.ts +1 -1
  62. package/src/core/driver.ts +1 -1
  63. package/src/core/errors.ts +14 -4
  64. package/src/core/ll_client.test.ts +9 -3
  65. package/src/core/ll_client.ts +81 -26
  66. package/src/core/unauth_client.test.ts +4 -4
  67. package/src/core/unauth_client.ts +7 -2
  68. package/src/core/websocket_stream.test.ts +19 -8
  69. package/src/core/websocket_stream.ts +173 -164
  70. package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.ts +179 -1
  71. package/src/proto-rest/index.ts +17 -2
  72. package/src/test/test_config.ts +13 -4
  73. /package/dist/__external/.pnpm/{@rollup_plugin-typescript@12.1.4_rollup@4.52.4_tslib@2.8.1_typescript@5.6.3 → @rollup_plugin-typescript@12.3.0_rollup@4.52.4_tslib@2.8.1_typescript@5.6.3}/__external/tslib/tslib.es6.cjs +0 -0
  74. /package/dist/__external/.pnpm/{@rollup_plugin-typescript@12.1.4_rollup@4.52.4_tslib@2.8.1_typescript@5.6.3 → @rollup_plugin-typescript@12.3.0_rollup@4.52.4_tslib@2.8.1_typescript@5.6.3}/__external/tslib/tslib.es6.js +0 -0
@@ -14,6 +14,7 @@ var index = require('../proto-rest/index.cjs');
14
14
  var tsHelpers = require('@milaboratories/ts-helpers');
15
15
  var code = require('../proto-grpc/google/rpc/code.cjs');
16
16
  var websocket_stream = require('./websocket_stream.cjs');
17
+ var api = require('../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.cjs');
17
18
 
18
19
  class WireClientProviderImpl {
19
20
  wireOpts;
@@ -34,8 +35,8 @@ class WireClientProviderImpl {
34
35
  }
35
36
  /** Abstract out low level networking and authorization details */
36
37
  class LLPlClient {
37
- ops;
38
38
  conf;
39
+ ops;
39
40
  /** Initial authorization information */
40
41
  authInformation;
41
42
  /** Will be executed by the client when it is required */
@@ -48,7 +49,7 @@ class LLPlClient {
48
49
  refreshTimestamp;
49
50
  _status = 'OK';
50
51
  statusListener;
51
- _wireProto = undefined;
52
+ _wireProto = 'grpc';
52
53
  _wireConn;
53
54
  _restInterceptors;
54
55
  _restMiddlewares;
@@ -56,11 +57,15 @@ class LLPlClient {
56
57
  providers = [];
57
58
  clientProvider;
58
59
  httpDispatcher;
59
- constructor(configOrAddress, ops = {}) {
60
+ static async build(configOrAddress, ops = {}) {
61
+ const conf = typeof configOrAddress === 'string' ? config.plAddressToConfig(configOrAddress) : configOrAddress;
62
+ const pl = new LLPlClient(conf, ops);
63
+ await pl.detectOptimalWireProtocol();
64
+ return pl;
65
+ }
66
+ constructor(conf, ops = {}) {
67
+ this.conf = conf;
60
68
  this.ops = ops;
61
- this.conf = typeof configOrAddress === 'string'
62
- ? config.plAddressToConfig(configOrAddress)
63
- : configOrAddress;
64
69
  const { auth: auth$1, statusListener } = ops;
65
70
  if (auth$1 !== undefined) {
66
71
  this.refreshTimestamp = auth.inferAuthRefreshTime(auth$1.authInformation, this.conf.authMaxRefreshSeconds);
@@ -80,7 +85,10 @@ class LLPlClient {
80
85
  this._restMiddlewares.push(this.createRestErrorMiddleware());
81
86
  this._grpcInterceptors.push(this.createGrpcErrorInterceptor());
82
87
  this.httpDispatcher = plHttp.defaultHttpDispatcher(this.conf.httpProxy);
83
- this.initWireConnection();
88
+ if (this.conf.wireProtocol) {
89
+ this._wireProto = this.conf.wireProtocol;
90
+ }
91
+ this.initWireConnection(this._wireProto);
84
92
  if (statusListener !== undefined) {
85
93
  this.statusListener = statusListener;
86
94
  statusListener(this._status);
@@ -99,12 +107,8 @@ class LLPlClient {
99
107
  }
100
108
  });
101
109
  }
102
- initWireConnection() {
103
- if (this._wireProto === undefined) {
104
- // TODO: implement automatic server mode detection
105
- this._wireProto = this.conf.wireProtocol ?? 'grpc';
106
- }
107
- switch (this._wireProto) {
110
+ initWireConnection(protocol) {
111
+ switch (protocol) {
108
112
  case 'rest':
109
113
  this.initRestConnection();
110
114
  return;
@@ -114,11 +118,11 @@ class LLPlClient {
114
118
  default:
115
119
  ((v) => {
116
120
  throw new Error(`Unsupported wire protocol '${v}'. Use one of: ${config.SUPPORTED_WIRE_PROTOCOLS.join(', ')}`);
117
- })(this._wireProto);
121
+ })(protocol);
118
122
  }
119
123
  }
120
124
  initRestConnection() {
121
- const dispatcher = plHttp.defaultHttpDispatcher(this.conf.httpProxy, this._restInterceptors);
125
+ const dispatcher = plHttp.defaultHttpDispatcher(this.conf.grpcProxy, this._restInterceptors);
122
126
  this._replaceWireConnection({ type: 'rest', Config: this.conf, Dispatcher: dispatcher, Middlewares: this._restMiddlewares });
123
127
  }
124
128
  /**
@@ -171,6 +175,7 @@ class LLPlClient {
171
175
  _replaceWireConnection(newConn) {
172
176
  const oldConn = this._wireConn;
173
177
  this._wireConn = newConn;
178
+ this._wireProto = newConn.type;
174
179
  // Reset all providers to let them reinitialize their clients
175
180
  for (let i = 0; i < this.providers.length; i++) {
176
181
  const provider = this.providers[i].deref();
@@ -214,6 +219,9 @@ class LLPlClient {
214
219
  get wireConnection() {
215
220
  return this._wireConn;
216
221
  }
222
+ get wireProtocol() {
223
+ return this._wireProto;
224
+ }
217
225
  /** Returns true if client is authenticated. Even with anonymous auth information
218
226
  * connection is considered authenticated. Unauthenticated clients are used for
219
227
  * login and similar tasks, see {@link UnauthenticatedPlClient}. */
@@ -377,6 +385,29 @@ class LLPlClient {
377
385
  return tsHelpers.notEmpty((await cl.GET('/v1/ping')).data);
378
386
  }
379
387
  }
388
+ /**
389
+ * Detects the best available wire protocol.
390
+ * If wireProtocol is explicitly configured, does nothing.
391
+ * Otherwise probes the current protocol via ping; if it fails, switches to the alternative.
392
+ */
393
+ async detectOptimalWireProtocol() {
394
+ if (this.conf.wireProtocol) {
395
+ return;
396
+ }
397
+ const retryOptions = {
398
+ type: 'exponentialBackoff',
399
+ maxAttempts: 80,
400
+ initialDelay: 30,
401
+ backoffMultiplier: 1.3,
402
+ jitter: 0.2,
403
+ maxDelay: 500,
404
+ };
405
+ await tsHelpers.retry(() => tsHelpers.withTimeout(this.ping(), 500), retryOptions, () => {
406
+ const protocol = this._wireProto === 'grpc' ? 'rest' : 'grpc';
407
+ this.initWireConnection(protocol);
408
+ return true;
409
+ });
410
+ }
380
411
  async license() {
381
412
  const cl = this.clientProvider.get();
382
413
  if (cl instanceof api_client.PlatformClient) {
@@ -422,20 +453,29 @@ class LLPlClient {
422
453
  timeout,
423
454
  });
424
455
  }
425
- if (this._wireProto === 'rest') {
456
+ const wireConn = this.wireConnection;
457
+ if (wireConn.type === 'rest') {
426
458
  // For REST/WebSocket protocol, timeout needs to be converted to AbortSignal
427
459
  if (timeout !== undefined) {
428
460
  totalAbortSignal = AbortSignal.any([totalAbortSignal, AbortSignal.timeout(timeout)]);
429
461
  }
462
+ // The gRPC transport has the auth interceptor that already handles it, but here we need to refresh the auth information to be safe.
463
+ this.refreshAuthInformationIfNeeded();
430
464
  const wsUrl = this.conf.ssl
431
465
  ? `wss://${this.conf.hostAndPort}/v1/ws/tx`
432
466
  : `ws://${this.conf.hostAndPort}/v1/ws/tx`;
433
- // The gRPC transport has the auth interceptor that already handles it, so we need to refresh the auth information here.
434
- this.refreshAuthInformationIfNeeded();
435
- const jwtToken = this.authInformation?.jwtToken;
436
- return new websocket_stream.WebSocketBiDiStream(wsUrl, totalAbortSignal, jwtToken);
467
+ return new websocket_stream.WebSocketBiDiStream(wsUrl, (msg) => api.TxAPI_ClientMessage.toBinary(msg), (data) => api.TxAPI_ServerMessage.fromBinary(new Uint8Array(data)), {
468
+ abortSignal: totalAbortSignal,
469
+ jwtToken: this.authInformation?.jwtToken,
470
+ dispatcher: wireConn.Dispatcher,
471
+ onComplete: async (stream) => stream.requests.send({
472
+ // Ask server to gracefully close the stream on its side, if not done yet.
473
+ requestId: 0,
474
+ request: { oneofKind: 'streamClose', streamClose: {} },
475
+ }),
476
+ });
437
477
  }
438
- throw new Error('tx is not supported for this wire protocol');
478
+ throw new Error(`transactions are not supported for wire protocol ${this._wireProto}`);
439
479
  });
440
480
  }
441
481
  /** Closes underlying transport */
@@ -1 +1 @@
1
- {"version":3,"file":"ll_client.cjs","sources":["../../src/core/ll_client.ts"],"sourcesContent":["import { PlatformClient as GrpcPlApiClient } from '../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client';\nimport type { ClientOptions, Interceptor } from '@grpc/grpc-js';\nimport {\n ChannelCredentials,\n InterceptingCall,\n status as GrpcStatus,\n compressionAlgorithms,\n} from '@grpc/grpc-js';\nimport type {\n AuthInformation,\n AuthOps,\n PlClientConfig,\n PlConnectionStatus,\n PlConnectionStatusListener,\n} from './config';\nimport { plAddressToConfig, type wireProtocol, SUPPORTED_WIRE_PROTOCOLS } from './config';\nimport type { GrpcOptions } from '@protobuf-ts/grpc-transport';\nimport { GrpcTransport } from '@protobuf-ts/grpc-transport';\nimport { LLPlTransaction } from './ll_transaction';\nimport { parsePlJwt } from '../util/pl';\nimport { type Dispatcher, interceptors } from 'undici';\nimport type { Middleware } from 'openapi-fetch';\nimport { inferAuthRefreshTime } from './auth';\nimport { defaultHttpDispatcher } from '@milaboratories/pl-http';\nimport type { WireClientProvider, WireClientProviderFactory, WireConnection } from './wire';\nimport { parseHttpAuth } from '@milaboratories/pl-model-common';\nimport type * as grpcTypes from '../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api';\nimport { type PlApiPaths, type PlRestClientType, createClient, parseResponseError } from '../proto-rest';\nimport { notEmpty } from '@milaboratories/ts-helpers';\nimport { Code } from '../proto-grpc/google/rpc/code';\nimport { WebSocketBiDiStream } from './websocket_stream';\n\nexport interface PlCallOps {\n timeout?: number;\n abortSignal?: AbortSignal;\n}\n\nclass WireClientProviderImpl<Client> implements WireClientProvider<Client> {\n private client: Client | undefined = undefined;\n\n constructor(private readonly wireOpts: () => WireConnection, private readonly clientConstructor: (wireOpts: WireConnection) => Client) {}\n\n public reset(): void {\n this.client = undefined;\n }\n\n public get(): Client {\n if (this.client === undefined)\n this.client = this.clientConstructor(this.wireOpts());\n return this.client;\n }\n}\n\n/** Abstract out low level networking and authorization details */\nexport class LLPlClient implements WireClientProviderFactory {\n public readonly conf: PlClientConfig;\n\n /** Initial authorization information */\n private authInformation?: AuthInformation;\n /** Will be executed by the client when it is required */\n private readonly onAuthUpdate?: (newInfo: AuthInformation) => void;\n /** Will be executed if auth-related error happens during normal client operation */\n private readonly onAuthError?: () => void;\n /** Will be executed by the client when it is required */\n private readonly onAuthRefreshProblem?: (error: unknown) => void;\n /** Threshold after which auth info refresh is required */\n private refreshTimestamp?: number;\n\n private _status: PlConnectionStatus = 'OK';\n private readonly statusListener?: PlConnectionStatusListener;\n\n private _wireProto: wireProtocol | undefined = undefined;\n private _wireConn!: WireConnection;\n\n private readonly _restInterceptors: Dispatcher.DispatcherComposeInterceptor[];\n private readonly _restMiddlewares: Middleware[];\n private readonly _grpcInterceptors: Interceptor[];\n private readonly providers: WeakRef<WireClientProviderImpl<any>>[] = [];\n\n public readonly clientProvider: WireClientProvider<PlRestClientType | GrpcPlApiClient>;\n\n public readonly httpDispatcher: Dispatcher;\n\n constructor(\n configOrAddress: PlClientConfig | string,\n private readonly ops: {\n auth?: AuthOps;\n statusListener?: PlConnectionStatusListener;\n shouldUseGzip?: boolean;\n } = {},\n ) {\n this.conf = typeof configOrAddress === 'string'\n ? plAddressToConfig(configOrAddress)\n : configOrAddress;\n\n const { auth, statusListener } = ops;\n\n if (auth !== undefined) {\n this.refreshTimestamp = inferAuthRefreshTime(\n auth.authInformation,\n this.conf.authMaxRefreshSeconds,\n );\n this.authInformation = auth.authInformation;\n this.onAuthUpdate = auth.onUpdate;\n this.onAuthRefreshProblem = auth.onUpdateError;\n this.onAuthError = auth.onAuthError;\n }\n\n this._restInterceptors = [];\n this._restMiddlewares = [];\n this._grpcInterceptors = [];\n\n if (auth !== undefined) {\n this._restInterceptors.push(this.createRestAuthInterceptor());\n this._grpcInterceptors.push(this.createGrpcAuthInterceptor());\n }\n this._restInterceptors.push(interceptors.retry({ statusCodes: [] })); // Handle errors with openapi-fetch middleware.\n this._restMiddlewares.push(this.createRestErrorMiddleware());\n this._grpcInterceptors.push(this.createGrpcErrorInterceptor());\n\n this.httpDispatcher = defaultHttpDispatcher(this.conf.httpProxy);\n\n this.initWireConnection();\n\n if (statusListener !== undefined) {\n this.statusListener = statusListener;\n statusListener(this._status);\n }\n\n this.clientProvider = this.createWireClientProvider((wireConn) => {\n if (wireConn.type === 'grpc') {\n return new GrpcPlApiClient(wireConn.Transport);\n } else {\n return createClient<PlApiPaths>({\n hostAndPort: wireConn.Config.hostAndPort,\n ssl: wireConn.Config.ssl,\n dispatcher: wireConn.Dispatcher,\n middlewares: wireConn.Middlewares,\n });\n }\n });\n }\n\n private initWireConnection() {\n if (this._wireProto === undefined) {\n // TODO: implement automatic server mode detection\n this._wireProto = this.conf.wireProtocol ?? 'grpc';\n }\n\n switch (this._wireProto) {\n case 'rest':\n this.initRestConnection();\n return;\n case 'grpc':\n this.initGrpcConnection(this.ops.shouldUseGzip ?? false);\n return;\n default:\n ((v: never) => {\n throw new Error(`Unsupported wire protocol '${v as string}'. Use one of: ${SUPPORTED_WIRE_PROTOCOLS.join(', ')}`);\n })(this._wireProto);\n }\n }\n\n private initRestConnection(): void {\n const dispatcher = defaultHttpDispatcher(this.conf.httpProxy, this._restInterceptors);\n this._replaceWireConnection({ type: 'rest', Config: this.conf, Dispatcher: dispatcher, Middlewares: this._restMiddlewares });\n }\n\n /**\n * Initializes (or reinitializes) _grpcTransport\n * @param gzip - whether to enable gzip compression\n */\n private initGrpcConnection(gzip: boolean) {\n const clientOptions: ClientOptions = {\n 'grpc.keepalive_time_ms': 30_000, // 30 seconds\n 'grpc.service_config_disable_resolution': 1, // Disable DNS TXT lookups for service config\n 'interceptors': this._grpcInterceptors,\n };\n\n if (gzip) clientOptions['grpc.default_compression_algorithm'] = compressionAlgorithms.gzip;\n\n //\n // Leaving it here for now\n // https://github.com/grpc/grpc-node/issues/2788\n //\n // We should implement message pooling algorithm to overcome hardcoded NO_DELAY behaviour\n // of HTTP/2 and allow our small messages to batch together.\n //\n const grpcOptions: GrpcOptions = {\n host: this.conf.hostAndPort,\n timeout: this.conf.defaultRequestTimeout,\n channelCredentials: this.conf.ssl\n ? ChannelCredentials.createSsl()\n : ChannelCredentials.createInsecure(),\n clientOptions,\n };\n\n const grpcProxy = typeof this.conf.grpcProxy === 'string'\n ? { url: this.conf.grpcProxy }\n : this.conf.grpcProxy;\n\n if (grpcProxy?.url) {\n const url = new URL(grpcProxy.url);\n if (grpcProxy.auth) {\n const parsed = parseHttpAuth(grpcProxy.auth);\n if (parsed.scheme !== 'Basic') {\n throw new Error(`Unsupported auth scheme: ${parsed.scheme as string}.`);\n }\n url.username = parsed.username;\n url.password = parsed.password;\n }\n process.env.grpc_proxy = url.toString();\n } else {\n delete process.env.grpc_proxy;\n }\n\n this._replaceWireConnection({ type: 'grpc', Transport: new GrpcTransport(grpcOptions) });\n }\n\n private _replaceWireConnection(newConn: WireConnection): void {\n const oldConn = this._wireConn;\n this._wireConn = newConn;\n\n // Reset all providers to let them reinitialize their clients\n for (let i = 0; i < this.providers.length; i++) {\n const provider = this.providers[i].deref();\n if (provider === undefined) {\n // at the same time we need to remove providers that are no longer valid\n this.providers.splice(i, 1);\n i--;\n } else {\n provider.reset();\n }\n }\n\n if (oldConn !== undefined && oldConn.type === 'grpc') oldConn.Transport.close();\n }\n\n private providerCleanupCounter = 0;\n\n /**\n * Creates a provider for a grpc client. Returned provider will create fresh client whenever the underlying transport is reset.\n *\n * @param clientConstructor - a factory function that creates a grpc client\n */\n public createWireClientProvider<Client>(clientConstructor: (transport: WireConnection) => Client): WireClientProvider<Client> {\n // We need to cleanup providers periodically to avoid memory leaks.\n // This is a simple heuristic to avoid memory leaks.\n // We could use a more sophisticated algorithm, but this is good enough for now.\n this.providerCleanupCounter++;\n if (this.providerCleanupCounter >= 16) {\n for (let i = 0; i < this.providers.length; i++) {\n const provider = this.providers[i].deref();\n if (provider === undefined) {\n this.providers.splice(i, 1);\n i--;\n }\n }\n this.providerCleanupCounter = 0;\n }\n\n const provider = new WireClientProviderImpl<Client>(() => this._wireConn, clientConstructor);\n this.providers.push(new WeakRef(provider));\n return provider;\n }\n\n public get wireConnection(): WireConnection {\n return this._wireConn;\n }\n\n /** Returns true if client is authenticated. Even with anonymous auth information\n * connection is considered authenticated. Unauthenticated clients are used for\n * login and similar tasks, see {@link UnauthenticatedPlClient}. */\n public get authenticated(): boolean {\n return this.authInformation !== undefined;\n }\n\n /** null means anonymous connection */\n public get authUser(): string | null {\n if (!this.authenticated) throw new Error('Client is not authenticated');\n if (this.authInformation?.jwtToken)\n return parsePlJwt(this.authInformation?.jwtToken).user.login;\n else return null;\n }\n\n private updateStatus(newStatus: PlConnectionStatus) {\n process.nextTick(() => {\n if (this._status !== newStatus) {\n this._status = newStatus;\n if (this.statusListener !== undefined) this.statusListener(this._status);\n if (this.onAuthError !== undefined) this.onAuthError();\n }\n });\n }\n\n public get status(): PlConnectionStatus {\n return this._status;\n }\n\n private authRefreshInProgress: boolean = false;\n\n private refreshAuthInformationIfNeeded(): void {\n if (\n this.refreshTimestamp === undefined\n || Date.now() < this.refreshTimestamp\n || this.authRefreshInProgress\n || this._status === 'Unauthenticated'\n )\n return;\n\n // Running refresh in background`\n this.authRefreshInProgress = true;\n void (async () => {\n try {\n const token = await this.getJwtToken(BigInt(this.conf.authTTLSeconds));\n this.authInformation = { jwtToken: token };\n this.refreshTimestamp = inferAuthRefreshTime(\n this.authInformation,\n this.conf.authMaxRefreshSeconds,\n );\n if (this.onAuthUpdate) this.onAuthUpdate(this.authInformation);\n } catch (e: unknown) {\n if (this.onAuthRefreshProblem) this.onAuthRefreshProblem(e);\n } finally {\n this.authRefreshInProgress = false;\n }\n })();\n }\n\n /**\n * Creates middleware that parses error responses and handles them centrally.\n * This middleware runs before openapi-fetch parses the response, so we need to\n * manually parse the response body for error responses.\n */\n private createRestErrorMiddleware(): Middleware {\n return {\n onResponse: async ({ request: _request, response, options: _options }) => {\n const { body: body, ...resOptions } = response;\n\n if ([502, 503, 504].includes(response.status)) {\n // Service unavailable, bad gateway, gateway timeout\n this.updateStatus('Disconnected');\n return new Response(body, { ...resOptions, status: response.status });\n }\n\n const respErr = await parseResponseError(response);\n if (!respErr.error) {\n // No error: nice!\n return new Response(respErr.origBody ?? body, { ...resOptions, status: response.status });\n }\n\n if (typeof respErr.error === 'string') {\n // Non-standard error or normal response: let later middleware to deal wit it.\n return new Response(respErr.error, { ...resOptions, status: response.status });\n }\n\n if (respErr.error.code === Code.UNAUTHENTICATED) {\n this.updateStatus('Unauthenticated');\n }\n\n // Let later middleware to deal with standard gRPC error.\n return new Response(respErr.origBody, { ...resOptions, status: response.status });\n },\n };\n }\n\n /** Detects certain errors and update client status accordingly when using GRPC wire connection */\n private createGrpcErrorInterceptor(): Interceptor {\n return (options, nextCall) => {\n return new InterceptingCall(nextCall(options), {\n start: (metadata, listener, next) => {\n next(metadata, {\n onReceiveStatus: (status, next) => {\n if (status.code == GrpcStatus.UNAUTHENTICATED)\n // (!!!) don't change to \"===\"\n this.updateStatus('Unauthenticated');\n if (status.code == GrpcStatus.UNAVAILABLE)\n // (!!!) don't change to \"===\"\n this.updateStatus('Disconnected');\n next(status);\n },\n });\n },\n });\n };\n }\n\n private createRestAuthInterceptor(): Dispatcher.DispatcherComposeInterceptor {\n return (dispatch) => {\n return (options, handler) => {\n if (this.authInformation?.jwtToken !== undefined) {\n // TODO: check this magic really works and gets called\n options.headers = { ...options.headers, authorization: 'Bearer ' + this.authInformation.jwtToken };\n this.refreshAuthInformationIfNeeded();\n }\n\n return dispatch(options, handler);\n };\n };\n }\n\n /** Injects authentication information if needed */\n private createGrpcAuthInterceptor(): Interceptor {\n return (options, nextCall) => {\n return new InterceptingCall(nextCall(options), {\n start: (metadata, listener, next) => {\n if (this.authInformation?.jwtToken !== undefined) {\n metadata.set('authorization', 'Bearer ' + this.authInformation.jwtToken);\n this.refreshAuthInformationIfNeeded();\n next(metadata, listener);\n } else {\n next(metadata, listener);\n }\n },\n });\n };\n }\n\n public async getJwtToken(ttlSeconds: bigint, options?: { authorization?: string }): Promise<string> {\n const cl = this.clientProvider.get();\n\n if (cl instanceof GrpcPlApiClient) {\n const meta: Record<string, string> = {};\n if (options?.authorization) meta.authorization = options.authorization;\n return (await cl.getJWTToken({ expiration: { seconds: ttlSeconds, nanos: 0 } }, { meta }).response).token;\n } else {\n const headers: Record<string, string> = {};\n if (options?.authorization) headers.authorization = options.authorization;\n const resp = cl.POST('/v1/auth/jwt-token', {\n body: { expiration: `${ttlSeconds}s` },\n headers,\n });\n return notEmpty((await resp).data).token;\n }\n }\n\n public async ping(): Promise<grpcTypes.MaintenanceAPI_Ping_Response> {\n const cl = this.clientProvider.get();\n if (cl instanceof GrpcPlApiClient) {\n return (await cl.ping({})).response;\n } else {\n return notEmpty((await cl.GET('/v1/ping')).data);\n }\n }\n\n public async license(): Promise<grpcTypes.MaintenanceAPI_License_Response> {\n const cl = this.clientProvider.get();\n if (cl instanceof GrpcPlApiClient) {\n return (await cl.license({})).response;\n } else {\n const resp = notEmpty((await cl.GET('/v1/license')).data);\n return {\n status: resp.status,\n isOk: resp.isOk,\n responseBody: Uint8Array.from(Buffer.from(resp.responseBody)),\n };\n }\n }\n\n public async authMethods(): Promise<grpcTypes.AuthAPI_ListMethods_Response> {\n const cl = this.clientProvider.get();\n if (cl instanceof GrpcPlApiClient) {\n return (await cl.authMethods({})).response;\n } else {\n return notEmpty((await cl.GET('/v1/auth/methods')).data);\n }\n }\n\n public async txSync(txId: bigint): Promise<void> {\n const cl = this.clientProvider.get();\n if (cl instanceof GrpcPlApiClient) {\n await cl.txSync({ txId: BigInt(txId) });\n } else {\n (await cl.POST('/v1/tx-sync', { body: { txId: txId.toString() } }));\n }\n }\n\n createTx(rw: boolean, ops: PlCallOps = {}): LLPlTransaction {\n return new LLPlTransaction((abortSignal) => {\n let totalAbortSignal = abortSignal;\n if (ops.abortSignal) totalAbortSignal = AbortSignal.any([totalAbortSignal, ops.abortSignal]);\n\n const timeout = ops.timeout ?? (rw ? this.conf.defaultRWTransactionTimeout : this.conf.defaultROTransactionTimeout);\n\n const cl = this.clientProvider.get();\n if (cl instanceof GrpcPlApiClient) {\n return cl.tx({\n abort: totalAbortSignal,\n timeout,\n });\n }\n\n if (this._wireProto === 'rest') {\n // For REST/WebSocket protocol, timeout needs to be converted to AbortSignal\n if (timeout !== undefined) {\n totalAbortSignal = AbortSignal.any([totalAbortSignal, AbortSignal.timeout(timeout)]);\n }\n const wsUrl = this.conf.ssl\n ? `wss://${this.conf.hostAndPort}/v1/ws/tx`\n : `ws://${this.conf.hostAndPort}/v1/ws/tx`;\n\n // The gRPC transport has the auth interceptor that already handles it, so we need to refresh the auth information here.\n this.refreshAuthInformationIfNeeded();\n const jwtToken = this.authInformation?.jwtToken;\n\n return new WebSocketBiDiStream(wsUrl, totalAbortSignal, jwtToken);\n }\n throw new Error('tx is not supported for this wire protocol');\n });\n }\n\n /** Closes underlying transport */\n public async close() {\n if (this.wireConnection.type === 'grpc') {\n this.wireConnection.Transport.close();\n } else {\n // TODO: close all WS connections\n }\n await this.httpDispatcher.destroy();\n }\n}\n"],"names":["plAddressToConfig","auth","inferAuthRefreshTime","interceptors","defaultHttpDispatcher","GrpcPlApiClient","createClient","SUPPORTED_WIRE_PROTOCOLS","compressionAlgorithms","ChannelCredentials","parseHttpAuth","GrpcTransport","parsePlJwt","parseResponseError","Code","InterceptingCall","GrpcStatus","notEmpty","LLPlTransaction","WebSocketBiDiStream"],"mappings":"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"}
1
+ {"version":3,"file":"ll_client.cjs","sources":["../../src/core/ll_client.ts"],"sourcesContent":["import { PlatformClient as GrpcPlApiClient } from '../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client';\nimport type { ClientOptions, Interceptor } from '@grpc/grpc-js';\nimport {\n ChannelCredentials,\n InterceptingCall,\n status as GrpcStatus,\n compressionAlgorithms,\n} from '@grpc/grpc-js';\nimport type {\n AuthInformation,\n AuthOps,\n PlClientConfig,\n PlConnectionStatus,\n PlConnectionStatusListener,\n} from './config';\nimport { plAddressToConfig, type wireProtocol, SUPPORTED_WIRE_PROTOCOLS } from './config';\nimport type { GrpcOptions } from '@protobuf-ts/grpc-transport';\nimport { GrpcTransport } from '@protobuf-ts/grpc-transport';\nimport { LLPlTransaction } from './ll_transaction';\nimport { parsePlJwt } from '../util/pl';\nimport { type Dispatcher, interceptors } from 'undici';\nimport type { Middleware } from 'openapi-fetch';\nimport { inferAuthRefreshTime } from './auth';\nimport { defaultHttpDispatcher } from '@milaboratories/pl-http';\nimport type { WireClientProvider, WireClientProviderFactory, WireConnection } from './wire';\nimport { parseHttpAuth } from '@milaboratories/pl-model-common';\nimport type * as grpcTypes from '../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api';\nimport { type PlApiPaths, type PlRestClientType, createClient, parseResponseError } from '../proto-rest';\nimport { notEmpty, retry, withTimeout, type RetryOptions } from '@milaboratories/ts-helpers';\nimport { Code } from '../proto-grpc/google/rpc/code';\nimport { WebSocketBiDiStream } from './websocket_stream';\nimport { TxAPI_ClientMessage, TxAPI_ServerMessage } from '../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api';\n\nexport interface PlCallOps {\n timeout?: number;\n abortSignal?: AbortSignal;\n}\n\nclass WireClientProviderImpl<Client> implements WireClientProvider<Client> {\n private client: Client | undefined = undefined;\n\n constructor(private readonly wireOpts: () => WireConnection, private readonly clientConstructor: (wireOpts: WireConnection) => Client) {}\n\n public reset(): void {\n this.client = undefined;\n }\n\n public get(): Client {\n if (this.client === undefined)\n this.client = this.clientConstructor(this.wireOpts());\n return this.client;\n }\n}\n\n/** Abstract out low level networking and authorization details */\nexport class LLPlClient implements WireClientProviderFactory {\n /** Initial authorization information */\n private authInformation?: AuthInformation;\n /** Will be executed by the client when it is required */\n private readonly onAuthUpdate?: (newInfo: AuthInformation) => void;\n /** Will be executed if auth-related error happens during normal client operation */\n private readonly onAuthError?: () => void;\n /** Will be executed by the client when it is required */\n private readonly onAuthRefreshProblem?: (error: unknown) => void;\n /** Threshold after which auth info refresh is required */\n private refreshTimestamp?: number;\n\n private _status: PlConnectionStatus = 'OK';\n private readonly statusListener?: PlConnectionStatusListener;\n\n private _wireProto: wireProtocol = 'grpc';\n private _wireConn!: WireConnection;\n\n private readonly _restInterceptors: Dispatcher.DispatcherComposeInterceptor[];\n private readonly _restMiddlewares: Middleware[];\n private readonly _grpcInterceptors: Interceptor[];\n private readonly providers: WeakRef<WireClientProviderImpl<any>>[] = [];\n\n public readonly clientProvider: WireClientProvider<PlRestClientType | GrpcPlApiClient>;\n\n public readonly httpDispatcher: Dispatcher;\n\n public static async build(\n configOrAddress: PlClientConfig | string,\n ops: {\n auth?: AuthOps;\n statusListener?: PlConnectionStatusListener;\n shouldUseGzip?: boolean;\n } = {},\n ) {\n const conf = typeof configOrAddress === 'string' ? plAddressToConfig(configOrAddress) : configOrAddress;\n\n const pl = new LLPlClient(conf, ops);\n await pl.detectOptimalWireProtocol();\n return pl;\n }\n\n private constructor(\n public readonly conf: PlClientConfig,\n private readonly ops: {\n auth?: AuthOps;\n statusListener?: PlConnectionStatusListener;\n shouldUseGzip?: boolean;\n } = {},\n ) {\n const { auth, statusListener } = ops;\n\n if (auth !== undefined) {\n this.refreshTimestamp = inferAuthRefreshTime(\n auth.authInformation,\n this.conf.authMaxRefreshSeconds,\n );\n this.authInformation = auth.authInformation;\n this.onAuthUpdate = auth.onUpdate;\n this.onAuthRefreshProblem = auth.onUpdateError;\n this.onAuthError = auth.onAuthError;\n }\n\n this._restInterceptors = [];\n this._restMiddlewares = [];\n this._grpcInterceptors = [];\n\n if (auth !== undefined) {\n this._restInterceptors.push(this.createRestAuthInterceptor());\n this._grpcInterceptors.push(this.createGrpcAuthInterceptor());\n }\n this._restInterceptors.push(interceptors.retry({ statusCodes: [] })); // Handle errors with openapi-fetch middleware.\n this._restMiddlewares.push(this.createRestErrorMiddleware());\n this._grpcInterceptors.push(this.createGrpcErrorInterceptor());\n\n this.httpDispatcher = defaultHttpDispatcher(this.conf.httpProxy);\n if (this.conf.wireProtocol) {\n this._wireProto = this.conf.wireProtocol;\n }\n\n this.initWireConnection(this._wireProto);\n\n if (statusListener !== undefined) {\n this.statusListener = statusListener;\n statusListener(this._status);\n }\n\n this.clientProvider = this.createWireClientProvider((wireConn) => {\n if (wireConn.type === 'grpc') {\n return new GrpcPlApiClient(wireConn.Transport);\n } else {\n return createClient<PlApiPaths>({\n hostAndPort: wireConn.Config.hostAndPort,\n ssl: wireConn.Config.ssl,\n dispatcher: wireConn.Dispatcher,\n middlewares: wireConn.Middlewares,\n });\n }\n });\n }\n\n private initWireConnection(protocol: wireProtocol) {\n switch (protocol) {\n case 'rest':\n this.initRestConnection();\n return;\n case 'grpc':\n this.initGrpcConnection(this.ops.shouldUseGzip ?? false);\n return;\n default:\n ((v: never) => {\n throw new Error(`Unsupported wire protocol '${v as string}'. Use one of: ${SUPPORTED_WIRE_PROTOCOLS.join(', ')}`);\n })(protocol);\n }\n }\n\n private initRestConnection(): void {\n const dispatcher = defaultHttpDispatcher(this.conf.grpcProxy, this._restInterceptors);\n this._replaceWireConnection({ type: 'rest', Config: this.conf, Dispatcher: dispatcher, Middlewares: this._restMiddlewares });\n }\n\n /**\n * Initializes (or reinitializes) _grpcTransport\n * @param gzip - whether to enable gzip compression\n */\n private initGrpcConnection(gzip: boolean) {\n const clientOptions: ClientOptions = {\n 'grpc.keepalive_time_ms': 30_000, // 30 seconds\n 'grpc.service_config_disable_resolution': 1, // Disable DNS TXT lookups for service config\n 'interceptors': this._grpcInterceptors,\n };\n\n if (gzip) clientOptions['grpc.default_compression_algorithm'] = compressionAlgorithms.gzip;\n\n //\n // Leaving it here for now\n // https://github.com/grpc/grpc-node/issues/2788\n //\n // We should implement message pooling algorithm to overcome hardcoded NO_DELAY behaviour\n // of HTTP/2 and allow our small messages to batch together.\n //\n const grpcOptions: GrpcOptions = {\n host: this.conf.hostAndPort,\n timeout: this.conf.defaultRequestTimeout,\n channelCredentials: this.conf.ssl\n ? ChannelCredentials.createSsl()\n : ChannelCredentials.createInsecure(),\n clientOptions,\n };\n\n const grpcProxy = typeof this.conf.grpcProxy === 'string'\n ? { url: this.conf.grpcProxy }\n : this.conf.grpcProxy;\n\n if (grpcProxy?.url) {\n const url = new URL(grpcProxy.url);\n if (grpcProxy.auth) {\n const parsed = parseHttpAuth(grpcProxy.auth);\n if (parsed.scheme !== 'Basic') {\n throw new Error(`Unsupported auth scheme: ${parsed.scheme as string}.`);\n }\n url.username = parsed.username;\n url.password = parsed.password;\n }\n process.env.grpc_proxy = url.toString();\n } else {\n delete process.env.grpc_proxy;\n }\n\n this._replaceWireConnection({ type: 'grpc', Transport: new GrpcTransport(grpcOptions) });\n }\n\n private _replaceWireConnection(newConn: WireConnection): void {\n const oldConn = this._wireConn;\n this._wireConn = newConn;\n this._wireProto = newConn.type;\n\n // Reset all providers to let them reinitialize their clients\n for (let i = 0; i < this.providers.length; i++) {\n const provider = this.providers[i].deref();\n if (provider === undefined) {\n // at the same time we need to remove providers that are no longer valid\n this.providers.splice(i, 1);\n i--;\n } else {\n provider.reset();\n }\n }\n\n if (oldConn !== undefined && oldConn.type === 'grpc') oldConn.Transport.close();\n }\n\n private providerCleanupCounter = 0;\n\n /**\n * Creates a provider for a grpc client. Returned provider will create fresh client whenever the underlying transport is reset.\n *\n * @param clientConstructor - a factory function that creates a grpc client\n */\n public createWireClientProvider<Client>(clientConstructor: (transport: WireConnection) => Client): WireClientProvider<Client> {\n // We need to cleanup providers periodically to avoid memory leaks.\n // This is a simple heuristic to avoid memory leaks.\n // We could use a more sophisticated algorithm, but this is good enough for now.\n this.providerCleanupCounter++;\n if (this.providerCleanupCounter >= 16) {\n for (let i = 0; i < this.providers.length; i++) {\n const provider = this.providers[i].deref();\n if (provider === undefined) {\n this.providers.splice(i, 1);\n i--;\n }\n }\n this.providerCleanupCounter = 0;\n }\n\n const provider = new WireClientProviderImpl<Client>(() => this._wireConn, clientConstructor);\n this.providers.push(new WeakRef(provider));\n return provider;\n }\n\n public get wireConnection(): WireConnection {\n return this._wireConn;\n }\n\n public get wireProtocol(): wireProtocol | undefined {\n return this._wireProto;\n }\n\n /** Returns true if client is authenticated. Even with anonymous auth information\n * connection is considered authenticated. Unauthenticated clients are used for\n * login and similar tasks, see {@link UnauthenticatedPlClient}. */\n public get authenticated(): boolean {\n return this.authInformation !== undefined;\n }\n\n /** null means anonymous connection */\n public get authUser(): string | null {\n if (!this.authenticated) throw new Error('Client is not authenticated');\n if (this.authInformation?.jwtToken)\n return parsePlJwt(this.authInformation?.jwtToken).user.login;\n else return null;\n }\n\n private updateStatus(newStatus: PlConnectionStatus) {\n process.nextTick(() => {\n if (this._status !== newStatus) {\n this._status = newStatus;\n if (this.statusListener !== undefined) this.statusListener(this._status);\n if (this.onAuthError !== undefined) this.onAuthError();\n }\n });\n }\n\n public get status(): PlConnectionStatus {\n return this._status;\n }\n\n private authRefreshInProgress: boolean = false;\n\n private refreshAuthInformationIfNeeded(): void {\n if (\n this.refreshTimestamp === undefined\n || Date.now() < this.refreshTimestamp\n || this.authRefreshInProgress\n || this._status === 'Unauthenticated'\n )\n return;\n\n // Running refresh in background`\n this.authRefreshInProgress = true;\n void (async () => {\n try {\n const token = await this.getJwtToken(BigInt(this.conf.authTTLSeconds));\n this.authInformation = { jwtToken: token };\n this.refreshTimestamp = inferAuthRefreshTime(\n this.authInformation,\n this.conf.authMaxRefreshSeconds,\n );\n if (this.onAuthUpdate) this.onAuthUpdate(this.authInformation);\n } catch (e: unknown) {\n if (this.onAuthRefreshProblem) this.onAuthRefreshProblem(e);\n } finally {\n this.authRefreshInProgress = false;\n }\n })();\n }\n\n /**\n * Creates middleware that parses error responses and handles them centrally.\n * This middleware runs before openapi-fetch parses the response, so we need to\n * manually parse the response body for error responses.\n */\n private createRestErrorMiddleware(): Middleware {\n return {\n onResponse: async ({ request: _request, response, options: _options }) => {\n const { body: body, ...resOptions } = response;\n\n if ([502, 503, 504].includes(response.status)) {\n // Service unavailable, bad gateway, gateway timeout\n this.updateStatus('Disconnected');\n return new Response(body, { ...resOptions, status: response.status });\n }\n\n const respErr = await parseResponseError(response);\n if (!respErr.error) {\n // No error: nice!\n return new Response(respErr.origBody ?? body, { ...resOptions, status: response.status });\n }\n\n if (typeof respErr.error === 'string') {\n // Non-standard error or normal response: let later middleware to deal wit it.\n return new Response(respErr.error, { ...resOptions, status: response.status });\n }\n\n if (respErr.error.code === Code.UNAUTHENTICATED) {\n this.updateStatus('Unauthenticated');\n }\n\n // Let later middleware to deal with standard gRPC error.\n return new Response(respErr.origBody, { ...resOptions, status: response.status });\n },\n };\n }\n\n /** Detects certain errors and update client status accordingly when using GRPC wire connection */\n private createGrpcErrorInterceptor(): Interceptor {\n return (options, nextCall) => {\n return new InterceptingCall(nextCall(options), {\n start: (metadata, listener, next) => {\n next(metadata, {\n onReceiveStatus: (status, next) => {\n if (status.code == GrpcStatus.UNAUTHENTICATED)\n // (!!!) don't change to \"===\"\n this.updateStatus('Unauthenticated');\n if (status.code == GrpcStatus.UNAVAILABLE)\n // (!!!) don't change to \"===\"\n this.updateStatus('Disconnected');\n next(status);\n },\n });\n },\n });\n };\n }\n\n private createRestAuthInterceptor(): Dispatcher.DispatcherComposeInterceptor {\n return (dispatch) => {\n return (options, handler) => {\n if (this.authInformation?.jwtToken !== undefined) {\n // TODO: check this magic really works and gets called\n options.headers = { ...options.headers, authorization: 'Bearer ' + this.authInformation.jwtToken };\n this.refreshAuthInformationIfNeeded();\n }\n\n return dispatch(options, handler);\n };\n };\n }\n\n /** Injects authentication information if needed */\n private createGrpcAuthInterceptor(): Interceptor {\n return (options, nextCall) => {\n return new InterceptingCall(nextCall(options), {\n start: (metadata, listener, next) => {\n if (this.authInformation?.jwtToken !== undefined) {\n metadata.set('authorization', 'Bearer ' + this.authInformation.jwtToken);\n this.refreshAuthInformationIfNeeded();\n next(metadata, listener);\n } else {\n next(metadata, listener);\n }\n },\n });\n };\n }\n\n public async getJwtToken(ttlSeconds: bigint, options?: { authorization?: string }): Promise<string> {\n const cl = this.clientProvider.get();\n\n if (cl instanceof GrpcPlApiClient) {\n const meta: Record<string, string> = {};\n if (options?.authorization) meta.authorization = options.authorization;\n return (await cl.getJWTToken({ expiration: { seconds: ttlSeconds, nanos: 0 } }, { meta }).response).token;\n } else {\n const headers: Record<string, string> = {};\n if (options?.authorization) headers.authorization = options.authorization;\n const resp = cl.POST('/v1/auth/jwt-token', {\n body: { expiration: `${ttlSeconds}s` },\n headers,\n });\n return notEmpty((await resp).data).token;\n }\n }\n\n public async ping(): Promise<grpcTypes.MaintenanceAPI_Ping_Response> {\n const cl = this.clientProvider.get();\n if (cl instanceof GrpcPlApiClient) {\n return (await cl.ping({})).response;\n } else {\n return notEmpty((await cl.GET('/v1/ping')).data);\n }\n }\n\n /**\n * Detects the best available wire protocol.\n * If wireProtocol is explicitly configured, does nothing.\n * Otherwise probes the current protocol via ping; if it fails, switches to the alternative.\n */\n private async detectOptimalWireProtocol() {\n if (this.conf.wireProtocol) {\n return;\n }\n\n const retryOptions: RetryOptions = {\n type: 'exponentialBackoff',\n maxAttempts: 80,\n initialDelay: 30,\n backoffMultiplier: 1.3,\n jitter: 0.2,\n maxDelay: 500,\n };\n\n await retry(() => withTimeout(this.ping(), 500), retryOptions, () => {\n const protocol = this._wireProto === 'grpc' ? 'rest' : 'grpc';\n this.initWireConnection(protocol);\n return true;\n });\n }\n\n public async license(): Promise<grpcTypes.MaintenanceAPI_License_Response> {\n const cl = this.clientProvider.get();\n if (cl instanceof GrpcPlApiClient) {\n return (await cl.license({})).response;\n } else {\n const resp = notEmpty((await cl.GET('/v1/license')).data);\n return {\n status: resp.status,\n isOk: resp.isOk,\n responseBody: Uint8Array.from(Buffer.from(resp.responseBody)),\n };\n }\n }\n\n public async authMethods(): Promise<grpcTypes.AuthAPI_ListMethods_Response> {\n const cl = this.clientProvider.get();\n if (cl instanceof GrpcPlApiClient) {\n return (await cl.authMethods({})).response;\n } else {\n return notEmpty((await cl.GET('/v1/auth/methods')).data);\n }\n }\n\n public async txSync(txId: bigint): Promise<void> {\n const cl = this.clientProvider.get();\n if (cl instanceof GrpcPlApiClient) {\n await cl.txSync({ txId: BigInt(txId) });\n } else {\n (await cl.POST('/v1/tx-sync', { body: { txId: txId.toString() } }));\n }\n }\n\n createTx(rw: boolean, ops: PlCallOps = {}): LLPlTransaction {\n return new LLPlTransaction((abortSignal) => {\n let totalAbortSignal = abortSignal;\n if (ops.abortSignal) totalAbortSignal = AbortSignal.any([totalAbortSignal, ops.abortSignal]);\n\n const timeout = ops.timeout ?? (rw ? this.conf.defaultRWTransactionTimeout : this.conf.defaultROTransactionTimeout);\n\n const cl = this.clientProvider.get();\n if (cl instanceof GrpcPlApiClient) {\n return cl.tx({\n abort: totalAbortSignal,\n timeout,\n });\n }\n\n const wireConn = this.wireConnection;\n if (wireConn.type === 'rest') {\n // For REST/WebSocket protocol, timeout needs to be converted to AbortSignal\n if (timeout !== undefined) {\n totalAbortSignal = AbortSignal.any([totalAbortSignal, AbortSignal.timeout(timeout)]);\n }\n\n // The gRPC transport has the auth interceptor that already handles it, but here we need to refresh the auth information to be safe.\n this.refreshAuthInformationIfNeeded();\n\n const wsUrl = this.conf.ssl\n ? `wss://${this.conf.hostAndPort}/v1/ws/tx`\n : `ws://${this.conf.hostAndPort}/v1/ws/tx`;\n\n return new WebSocketBiDiStream(wsUrl,\n (msg) => TxAPI_ClientMessage.toBinary(msg),\n (data) => TxAPI_ServerMessage.fromBinary(new Uint8Array(data)),\n {\n abortSignal: totalAbortSignal,\n jwtToken: this.authInformation?.jwtToken,\n dispatcher: wireConn.Dispatcher,\n\n onComplete: async (stream) => stream.requests.send({\n // Ask server to gracefully close the stream on its side, if not done yet.\n requestId: 0,\n request: { oneofKind: 'streamClose', streamClose: {} },\n }),\n },\n );\n }\n\n throw new Error(`transactions are not supported for wire protocol ${this._wireProto}`);\n });\n }\n\n /** Closes underlying transport */\n public async close() {\n if (this.wireConnection.type === 'grpc') {\n this.wireConnection.Transport.close();\n } else {\n // TODO: close all WS connections\n }\n await this.httpDispatcher.destroy();\n }\n}\n"],"names":["plAddressToConfig","auth","inferAuthRefreshTime","interceptors","defaultHttpDispatcher","GrpcPlApiClient","createClient","SUPPORTED_WIRE_PROTOCOLS","compressionAlgorithms","ChannelCredentials","parseHttpAuth","GrpcTransport","parsePlJwt","parseResponseError","Code","InterceptingCall","GrpcStatus","notEmpty","retry","withTimeout","LLPlTransaction","WebSocketBiDiStream","TxAPI_ClientMessage","TxAPI_ServerMessage"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { PlatformClient as GrpcPlApiClient } from '../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client';
2
2
  import type { AuthOps, PlClientConfig, PlConnectionStatus, PlConnectionStatusListener } from './config';
3
+ import { type wireProtocol } from './config';
3
4
  import { LLPlTransaction } from './ll_transaction';
4
5
  import { type Dispatcher } from 'undici';
5
6
  import type { WireClientProvider, WireClientProviderFactory, WireConnection } from './wire';
@@ -11,8 +12,8 @@ export interface PlCallOps {
11
12
  }
12
13
  /** Abstract out low level networking and authorization details */
13
14
  export declare class LLPlClient implements WireClientProviderFactory {
14
- private readonly ops;
15
15
  readonly conf: PlClientConfig;
16
+ private readonly ops;
16
17
  /** Initial authorization information */
17
18
  private authInformation?;
18
19
  /** Will be executed by the client when it is required */
@@ -33,11 +34,12 @@ export declare class LLPlClient implements WireClientProviderFactory {
33
34
  private readonly providers;
34
35
  readonly clientProvider: WireClientProvider<PlRestClientType | GrpcPlApiClient>;
35
36
  readonly httpDispatcher: Dispatcher;
36
- constructor(configOrAddress: PlClientConfig | string, ops?: {
37
+ static build(configOrAddress: PlClientConfig | string, ops?: {
37
38
  auth?: AuthOps;
38
39
  statusListener?: PlConnectionStatusListener;
39
40
  shouldUseGzip?: boolean;
40
- });
41
+ }): Promise<LLPlClient>;
42
+ private constructor();
41
43
  private initWireConnection;
42
44
  private initRestConnection;
43
45
  /**
@@ -54,6 +56,7 @@ export declare class LLPlClient implements WireClientProviderFactory {
54
56
  */
55
57
  createWireClientProvider<Client>(clientConstructor: (transport: WireConnection) => Client): WireClientProvider<Client>;
56
58
  get wireConnection(): WireConnection;
59
+ get wireProtocol(): wireProtocol | undefined;
57
60
  /** Returns true if client is authenticated. Even with anonymous auth information
58
61
  * connection is considered authenticated. Unauthenticated clients are used for
59
62
  * login and similar tasks, see {@link UnauthenticatedPlClient}. */
@@ -79,6 +82,12 @@ export declare class LLPlClient implements WireClientProviderFactory {
79
82
  authorization?: string;
80
83
  }): Promise<string>;
81
84
  ping(): Promise<grpcTypes.MaintenanceAPI_Ping_Response>;
85
+ /**
86
+ * Detects the best available wire protocol.
87
+ * If wireProtocol is explicitly configured, does nothing.
88
+ * Otherwise probes the current protocol via ping; if it fails, switches to the alternative.
89
+ */
90
+ private detectOptimalWireProtocol;
82
91
  license(): Promise<grpcTypes.MaintenanceAPI_License_Response>;
83
92
  authMethods(): Promise<grpcTypes.AuthAPI_ListMethods_Response>;
84
93
  txSync(txId: bigint): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"ll_client.d.ts","sourceRoot":"","sources":["../../src/core/ll_client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ll_client.d.ts","sourceRoot":"","sources":["../../src/core/ll_client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,IAAI,eAAe,EAAE,MAAM,sEAAsE,CAAC;AAQzH,OAAO,KAAK,EAEV,OAAO,EACP,cAAc,EACd,kBAAkB,EAClB,0BAA0B,EAC3B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAqB,KAAK,YAAY,EAA4B,MAAM,UAAU,CAAC;AAG1F,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EAAE,KAAK,UAAU,EAAgB,MAAM,QAAQ,CAAC;AAIvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE5F,OAAO,KAAK,KAAK,SAAS,MAAM,+DAA+D,CAAC;AAChG,OAAO,EAAmB,KAAK,gBAAgB,EAAoC,MAAM,eAAe,CAAC;AAMzG,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAkBD,kEAAkE;AAClE,qBAAa,UAAW,YAAW,yBAAyB;aA2CxC,IAAI,EAAE,cAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,GAAG;IA3CtB,wCAAwC;IACxC,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,yDAAyD;IACzD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAqC;IACnE,oFAAoF;IACpF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAa;IAC1C,yDAAyD;IACzD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAA2B;IACjE,0DAA0D;IAC1D,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAElC,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAA6B;IAE7D,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,SAAS,CAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA4C;IAC9E,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAe;IAChD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAgB;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8C;IAExE,SAAgB,cAAc,EAAE,kBAAkB,CAAC,gBAAgB,GAAG,eAAe,CAAC,CAAC;IAEvF,SAAgB,cAAc,EAAE,UAAU,CAAC;WAEvB,KAAK,CACvB,eAAe,EAAE,cAAc,GAAG,MAAM,EACxC,GAAG,GAAE;QACH,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,cAAc,CAAC,EAAE,0BAA0B,CAAC;QAC5C,aAAa,CAAC,EAAE,OAAO,CAAC;KACpB;IASR,OAAO;IA2DP,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,kBAAkB;IAK1B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA+C1B,OAAO,CAAC,sBAAsB;IAoB9B,OAAO,CAAC,sBAAsB,CAAK;IAEnC;;;;OAIG;IACI,wBAAwB,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC;IAqB7H,IAAW,cAAc,IAAI,cAAc,CAE1C;IAED,IAAW,YAAY,IAAI,YAAY,GAAG,SAAS,CAElD;IAED;;uEAEmE;IACnE,IAAW,aAAa,IAAI,OAAO,CAElC;IAED,sCAAsC;IACtC,IAAW,QAAQ,IAAI,MAAM,GAAG,IAAI,CAKnC;IAED,OAAO,CAAC,YAAY;IAUpB,IAAW,MAAM,IAAI,kBAAkB,CAEtC;IAED,OAAO,CAAC,qBAAqB,CAAkB;IAE/C,OAAO,CAAC,8BAA8B;IA4BtC;;;;OAIG;IACH,OAAO,CAAC,yBAAyB;IAgCjC,kGAAkG;IAClG,OAAO,CAAC,0BAA0B;IAoBlC,OAAO,CAAC,yBAAyB;IAcjC,mDAAmD;IACnD,OAAO,CAAC,yBAAyB;IAgBpB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAkBtF,IAAI,IAAI,OAAO,CAAC,SAAS,CAAC,4BAA4B,CAAC;IASpE;;;;OAIG;YACW,yBAAyB;IAqB1B,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC,+BAA+B,CAAC;IAc7D,WAAW,IAAI,OAAO,CAAC,SAAS,CAAC,4BAA4B,CAAC;IAS9D,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAShD,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,GAAE,SAAc,GAAG,eAAe;IAkD3D,kCAAkC;IACrB,KAAK;CAQnB"}
@@ -9,9 +9,10 @@ import { inferAuthRefreshTime } from './auth.js';
9
9
  import { defaultHttpDispatcher } from '@milaboratories/pl-http';
10
10
  import { parseHttpAuth } from '@milaboratories/pl-model-common';
11
11
  import { createClient, parseResponseError } from '../proto-rest/index.js';
12
- import { notEmpty } from '@milaboratories/ts-helpers';
12
+ import { notEmpty, retry, withTimeout } from '@milaboratories/ts-helpers';
13
13
  import { Code } from '../proto-grpc/google/rpc/code.js';
14
14
  import { WebSocketBiDiStream } from './websocket_stream.js';
15
+ import { TxAPI_ClientMessage, TxAPI_ServerMessage } from '../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.js';
15
16
 
16
17
  class WireClientProviderImpl {
17
18
  wireOpts;
@@ -32,8 +33,8 @@ class WireClientProviderImpl {
32
33
  }
33
34
  /** Abstract out low level networking and authorization details */
34
35
  class LLPlClient {
35
- ops;
36
36
  conf;
37
+ ops;
37
38
  /** Initial authorization information */
38
39
  authInformation;
39
40
  /** Will be executed by the client when it is required */
@@ -46,7 +47,7 @@ class LLPlClient {
46
47
  refreshTimestamp;
47
48
  _status = 'OK';
48
49
  statusListener;
49
- _wireProto = undefined;
50
+ _wireProto = 'grpc';
50
51
  _wireConn;
51
52
  _restInterceptors;
52
53
  _restMiddlewares;
@@ -54,11 +55,15 @@ class LLPlClient {
54
55
  providers = [];
55
56
  clientProvider;
56
57
  httpDispatcher;
57
- constructor(configOrAddress, ops = {}) {
58
+ static async build(configOrAddress, ops = {}) {
59
+ const conf = typeof configOrAddress === 'string' ? plAddressToConfig(configOrAddress) : configOrAddress;
60
+ const pl = new LLPlClient(conf, ops);
61
+ await pl.detectOptimalWireProtocol();
62
+ return pl;
63
+ }
64
+ constructor(conf, ops = {}) {
65
+ this.conf = conf;
58
66
  this.ops = ops;
59
- this.conf = typeof configOrAddress === 'string'
60
- ? plAddressToConfig(configOrAddress)
61
- : configOrAddress;
62
67
  const { auth, statusListener } = ops;
63
68
  if (auth !== undefined) {
64
69
  this.refreshTimestamp = inferAuthRefreshTime(auth.authInformation, this.conf.authMaxRefreshSeconds);
@@ -78,7 +83,10 @@ class LLPlClient {
78
83
  this._restMiddlewares.push(this.createRestErrorMiddleware());
79
84
  this._grpcInterceptors.push(this.createGrpcErrorInterceptor());
80
85
  this.httpDispatcher = defaultHttpDispatcher(this.conf.httpProxy);
81
- this.initWireConnection();
86
+ if (this.conf.wireProtocol) {
87
+ this._wireProto = this.conf.wireProtocol;
88
+ }
89
+ this.initWireConnection(this._wireProto);
82
90
  if (statusListener !== undefined) {
83
91
  this.statusListener = statusListener;
84
92
  statusListener(this._status);
@@ -97,12 +105,8 @@ class LLPlClient {
97
105
  }
98
106
  });
99
107
  }
100
- initWireConnection() {
101
- if (this._wireProto === undefined) {
102
- // TODO: implement automatic server mode detection
103
- this._wireProto = this.conf.wireProtocol ?? 'grpc';
104
- }
105
- switch (this._wireProto) {
108
+ initWireConnection(protocol) {
109
+ switch (protocol) {
106
110
  case 'rest':
107
111
  this.initRestConnection();
108
112
  return;
@@ -112,11 +116,11 @@ class LLPlClient {
112
116
  default:
113
117
  ((v) => {
114
118
  throw new Error(`Unsupported wire protocol '${v}'. Use one of: ${SUPPORTED_WIRE_PROTOCOLS.join(', ')}`);
115
- })(this._wireProto);
119
+ })(protocol);
116
120
  }
117
121
  }
118
122
  initRestConnection() {
119
- const dispatcher = defaultHttpDispatcher(this.conf.httpProxy, this._restInterceptors);
123
+ const dispatcher = defaultHttpDispatcher(this.conf.grpcProxy, this._restInterceptors);
120
124
  this._replaceWireConnection({ type: 'rest', Config: this.conf, Dispatcher: dispatcher, Middlewares: this._restMiddlewares });
121
125
  }
122
126
  /**
@@ -169,6 +173,7 @@ class LLPlClient {
169
173
  _replaceWireConnection(newConn) {
170
174
  const oldConn = this._wireConn;
171
175
  this._wireConn = newConn;
176
+ this._wireProto = newConn.type;
172
177
  // Reset all providers to let them reinitialize their clients
173
178
  for (let i = 0; i < this.providers.length; i++) {
174
179
  const provider = this.providers[i].deref();
@@ -212,6 +217,9 @@ class LLPlClient {
212
217
  get wireConnection() {
213
218
  return this._wireConn;
214
219
  }
220
+ get wireProtocol() {
221
+ return this._wireProto;
222
+ }
215
223
  /** Returns true if client is authenticated. Even with anonymous auth information
216
224
  * connection is considered authenticated. Unauthenticated clients are used for
217
225
  * login and similar tasks, see {@link UnauthenticatedPlClient}. */
@@ -375,6 +383,29 @@ class LLPlClient {
375
383
  return notEmpty((await cl.GET('/v1/ping')).data);
376
384
  }
377
385
  }
386
+ /**
387
+ * Detects the best available wire protocol.
388
+ * If wireProtocol is explicitly configured, does nothing.
389
+ * Otherwise probes the current protocol via ping; if it fails, switches to the alternative.
390
+ */
391
+ async detectOptimalWireProtocol() {
392
+ if (this.conf.wireProtocol) {
393
+ return;
394
+ }
395
+ const retryOptions = {
396
+ type: 'exponentialBackoff',
397
+ maxAttempts: 80,
398
+ initialDelay: 30,
399
+ backoffMultiplier: 1.3,
400
+ jitter: 0.2,
401
+ maxDelay: 500,
402
+ };
403
+ await retry(() => withTimeout(this.ping(), 500), retryOptions, () => {
404
+ const protocol = this._wireProto === 'grpc' ? 'rest' : 'grpc';
405
+ this.initWireConnection(protocol);
406
+ return true;
407
+ });
408
+ }
378
409
  async license() {
379
410
  const cl = this.clientProvider.get();
380
411
  if (cl instanceof PlatformClient) {
@@ -420,20 +451,29 @@ class LLPlClient {
420
451
  timeout,
421
452
  });
422
453
  }
423
- if (this._wireProto === 'rest') {
454
+ const wireConn = this.wireConnection;
455
+ if (wireConn.type === 'rest') {
424
456
  // For REST/WebSocket protocol, timeout needs to be converted to AbortSignal
425
457
  if (timeout !== undefined) {
426
458
  totalAbortSignal = AbortSignal.any([totalAbortSignal, AbortSignal.timeout(timeout)]);
427
459
  }
460
+ // The gRPC transport has the auth interceptor that already handles it, but here we need to refresh the auth information to be safe.
461
+ this.refreshAuthInformationIfNeeded();
428
462
  const wsUrl = this.conf.ssl
429
463
  ? `wss://${this.conf.hostAndPort}/v1/ws/tx`
430
464
  : `ws://${this.conf.hostAndPort}/v1/ws/tx`;
431
- // The gRPC transport has the auth interceptor that already handles it, so we need to refresh the auth information here.
432
- this.refreshAuthInformationIfNeeded();
433
- const jwtToken = this.authInformation?.jwtToken;
434
- return new WebSocketBiDiStream(wsUrl, totalAbortSignal, jwtToken);
465
+ return new WebSocketBiDiStream(wsUrl, (msg) => TxAPI_ClientMessage.toBinary(msg), (data) => TxAPI_ServerMessage.fromBinary(new Uint8Array(data)), {
466
+ abortSignal: totalAbortSignal,
467
+ jwtToken: this.authInformation?.jwtToken,
468
+ dispatcher: wireConn.Dispatcher,
469
+ onComplete: async (stream) => stream.requests.send({
470
+ // Ask server to gracefully close the stream on its side, if not done yet.
471
+ requestId: 0,
472
+ request: { oneofKind: 'streamClose', streamClose: {} },
473
+ }),
474
+ });
435
475
  }
436
- throw new Error('tx is not supported for this wire protocol');
476
+ throw new Error(`transactions are not supported for wire protocol ${this._wireProto}`);
437
477
  });
438
478
  }
439
479
  /** Closes underlying transport */