@milaboratories/pl-client 2.16.8 → 2.16.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__external/.pnpm/{@rollup_plugin-typescript@12.1.4_rollup@4.52.4_tslib@2.7.0_typescript@5.6.3 → @rollup_plugin-typescript@12.1.4_rollup@4.52.4_tslib@2.8.1_typescript@5.6.3}/__external/tslib/tslib.es6.cjs +2 -2
- package/dist/__external/.pnpm/{@rollup_plugin-typescript@12.1.4_rollup@4.52.4_tslib@2.7.0_typescript@5.6.3 → @rollup_plugin-typescript@12.1.4_rollup@4.52.4_tslib@2.8.1_typescript@5.6.3}/__external/tslib/tslib.es6.cjs.map +1 -1
- package/dist/__external/.pnpm/{@rollup_plugin-typescript@12.1.4_rollup@4.52.4_tslib@2.7.0_typescript@5.6.3 → @rollup_plugin-typescript@12.1.4_rollup@4.52.4_tslib@2.8.1_typescript@5.6.3}/__external/tslib/tslib.es6.js +2 -2
- package/dist/__external/.pnpm/{@rollup_plugin-typescript@12.1.4_rollup@4.52.4_tslib@2.7.0_typescript@5.6.3 → @rollup_plugin-typescript@12.1.4_rollup@4.52.4_tslib@2.8.1_typescript@5.6.3}/__external/tslib/tslib.es6.js.map +1 -1
- package/dist/core/abstract_stream.d.ts +18 -0
- package/dist/core/abstract_stream.d.ts.map +1 -0
- package/dist/core/client.cjs +6 -6
- package/dist/core/client.cjs.map +1 -1
- package/dist/core/client.d.ts +3 -3
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +6 -6
- package/dist/core/client.js.map +1 -1
- package/dist/core/config.cjs +3 -0
- package/dist/core/config.cjs.map +1 -1
- package/dist/core/config.d.ts +4 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +3 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/driver.cjs +11 -0
- package/dist/core/driver.cjs.map +1 -1
- package/dist/core/driver.d.ts +8 -2
- package/dist/core/driver.d.ts.map +1 -1
- package/dist/core/driver.js +11 -1
- package/dist/core/driver.js.map +1 -1
- package/dist/core/errors.cjs +9 -0
- package/dist/core/errors.cjs.map +1 -1
- package/dist/core/errors.d.ts +1 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +9 -0
- package/dist/core/errors.js.map +1 -1
- package/dist/core/ll_client.cjs +194 -39
- package/dist/core/ll_client.cjs.map +1 -1
- package/dist/core/ll_client.d.ts +36 -15
- package/dist/core/ll_client.d.ts.map +1 -1
- package/dist/core/ll_client.js +195 -40
- package/dist/core/ll_client.js.map +1 -1
- package/dist/core/ll_transaction.cjs.map +1 -1
- package/dist/core/ll_transaction.d.ts +3 -3
- package/dist/core/ll_transaction.d.ts.map +1 -1
- package/dist/core/ll_transaction.js.map +1 -1
- package/dist/core/transaction.cjs +2 -2
- package/dist/core/transaction.cjs.map +1 -1
- package/dist/core/transaction.js +2 -2
- package/dist/core/transaction.js.map +1 -1
- package/dist/core/type_conversion.cjs +2 -2
- package/dist/core/type_conversion.cjs.map +1 -1
- package/dist/core/type_conversion.d.ts +2 -2
- package/dist/core/type_conversion.d.ts.map +1 -1
- package/dist/core/type_conversion.js +2 -2
- package/dist/core/type_conversion.js.map +1 -1
- package/dist/core/unauth_client.cjs +4 -8
- package/dist/core/unauth_client.cjs.map +1 -1
- package/dist/core/unauth_client.d.ts +1 -1
- package/dist/core/unauth_client.d.ts.map +1 -1
- package/dist/core/unauth_client.js +4 -8
- package/dist/core/unauth_client.js.map +1 -1
- package/dist/core/wire.d.ts +34 -0
- package/dist/core/wire.d.ts.map +1 -0
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/proto-grpc/github.com/googleapis/googleapis/google/rpc/status.cjs.map +1 -0
- package/dist/{proto → proto-grpc}/github.com/googleapis/googleapis/google/rpc/status.d.ts +4 -2
- package/dist/proto-grpc/github.com/googleapis/googleapis/google/rpc/status.d.ts.map +1 -0
- package/dist/proto-grpc/github.com/googleapis/googleapis/google/rpc/status.js.map +1 -0
- package/dist/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/api.cjs +25 -25
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.cjs.map +1 -0
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.cjs.map +1 -0
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.d.ts.map +1 -0
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.js.map +1 -0
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts.map +1 -0
- package/dist/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/api.js +25 -25
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.js.map +1 -0
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.cjs.map +1 -0
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.d.ts.map +1 -0
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.js.map +1 -0
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.cjs.map +1 -0
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.d.ts.map +1 -0
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.js.map +1 -0
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/import.d.ts.map +1 -0
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/resource_types.cjs.map +1 -0
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/resource_types.d.ts.map +1 -0
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/resource_types.js.map +1 -0
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/ws-test.d.ts +73 -0
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/ws-test.d.ts.map +1 -0
- package/dist/{proto → proto-grpc}/google/api/http.d.ts +28 -32
- package/dist/proto-grpc/google/api/http.d.ts.map +1 -0
- package/dist/proto-grpc/google/protobuf/any.cjs.map +1 -0
- package/dist/proto-grpc/google/protobuf/any.d.ts.map +1 -0
- package/dist/proto-grpc/google/protobuf/any.js.map +1 -0
- package/dist/{proto → proto-grpc}/google/protobuf/descriptor.d.ts +6 -152
- package/dist/proto-grpc/google/protobuf/descriptor.d.ts.map +1 -0
- package/dist/proto-grpc/google/protobuf/duration.cjs.map +1 -0
- package/dist/proto-grpc/google/protobuf/duration.d.ts.map +1 -0
- package/dist/proto-grpc/google/protobuf/duration.js.map +1 -0
- package/dist/proto-grpc/google/protobuf/empty.d.ts.map +1 -0
- package/dist/proto-grpc/google/protobuf/struct.d.ts.map +1 -0
- package/dist/proto-grpc/google/protobuf/timestamp.cjs.map +1 -0
- package/dist/proto-grpc/google/protobuf/timestamp.d.ts.map +1 -0
- package/dist/proto-grpc/google/protobuf/timestamp.js.map +1 -0
- package/dist/{proto → proto-grpc}/google/protobuf/wrappers.d.ts +0 -27
- package/dist/proto-grpc/google/protobuf/wrappers.d.ts.map +1 -0
- package/dist/proto-grpc/google/rpc/code.cjs +240 -0
- package/dist/proto-grpc/google/rpc/code.cjs.map +1 -0
- package/dist/proto-grpc/google/rpc/code.d.ts +219 -0
- package/dist/proto-grpc/google/rpc/code.d.ts.map +1 -0
- package/dist/proto-grpc/google/rpc/code.js +240 -0
- package/dist/proto-grpc/google/rpc/code.js.map +1 -0
- package/dist/proto-grpc/google/rpc/error_details.d.ts +654 -0
- package/dist/proto-grpc/google/rpc/error_details.d.ts.map +1 -0
- package/dist/proto-grpc/google/rpc/http.d.ts +121 -0
- package/dist/proto-grpc/google/rpc/http.d.ts.map +1 -0
- package/dist/proto-grpc/google/rpc/status.d.ts +55 -0
- package/dist/proto-grpc/google/rpc/status.d.ts.map +1 -0
- package/dist/proto-rest/index.cjs +64 -0
- package/dist/proto-rest/index.cjs.map +1 -0
- package/dist/proto-rest/index.d.ts +23 -0
- package/dist/proto-rest/index.d.ts.map +1 -0
- package/dist/proto-rest/index.js +61 -0
- package/dist/proto-rest/index.js.map +1 -0
- package/dist/proto-rest/plapi.d.ts +1488 -0
- package/dist/proto-rest/plapi.d.ts.map +1 -0
- package/package.json +7 -4
- package/src/core/abstract_stream.ts +25 -0
- package/src/core/client.ts +8 -8
- package/src/core/config.ts +9 -0
- package/src/core/driver.ts +13 -2
- package/src/core/errors.ts +7 -1
- package/src/core/ll_client.test.ts +1 -1
- package/src/core/ll_client.ts +212 -42
- package/src/core/ll_transaction.test.ts +1 -1
- package/src/core/ll_transaction.ts +4 -4
- package/src/core/transaction.ts +1 -1
- package/src/core/type_conversion.ts +3 -3
- package/src/core/unauth_client.test.ts +6 -0
- package/src/core/unauth_client.ts +8 -12
- package/src/core/wire.ts +40 -0
- package/src/index.ts +3 -1
- package/src/{proto → proto-grpc}/github.com/googleapis/googleapis/google/rpc/status.ts +5 -3
- package/src/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/api.ts +25 -25
- package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/ws-test.ts +209 -0
- package/src/{proto → proto-grpc}/google/api/http.ts +29 -33
- package/src/{proto → proto-grpc}/google/protobuf/descriptor.ts +11 -221
- package/src/{proto → proto-grpc}/google/protobuf/wrappers.ts +4 -38
- package/src/proto-grpc/google/rpc/code.ts +236 -0
- package/src/proto-grpc/google/rpc/error_details.ts +1386 -0
- package/src/proto-grpc/google/rpc/http.ts +307 -0
- package/src/proto-grpc/google/rpc/status.ts +127 -0
- package/src/proto-rest/index.ts +83 -0
- package/src/proto-rest/plapi.ts +1488 -0
- package/dist/core/grpc.d.ts +0 -16
- package/dist/core/grpc.d.ts.map +0 -1
- package/dist/core/http.d.ts +0 -2
- package/dist/core/http.d.ts.map +0 -1
- package/dist/proto/github.com/googleapis/googleapis/google/rpc/status.cjs.map +0 -1
- package/dist/proto/github.com/googleapis/googleapis/google/rpc/status.d.ts.map +0 -1
- package/dist/proto/github.com/googleapis/googleapis/google/rpc/status.js.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.d.ts +0 -40
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.d.ts +0 -116
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.d.ts +0 -46
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.d.ts +0 -170
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.d.ts +0 -51
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.d.ts +0 -176
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.d.ts +0 -131
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.d.ts +0 -320
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api.cjs.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api.client.cjs.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api.client.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api.client.js.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api.js.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api_types.cjs.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api_types.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api_types.js.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/base_types.cjs.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/base_types.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/base_types.js.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/import.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/resource_types.cjs.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/resource_types.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/resource_types.js.map +0 -1
- package/dist/proto/google/api/http.d.ts.map +0 -1
- package/dist/proto/google/protobuf/any.cjs.map +0 -1
- package/dist/proto/google/protobuf/any.d.ts.map +0 -1
- package/dist/proto/google/protobuf/any.js.map +0 -1
- package/dist/proto/google/protobuf/descriptor.d.ts.map +0 -1
- package/dist/proto/google/protobuf/duration.cjs.map +0 -1
- package/dist/proto/google/protobuf/duration.d.ts.map +0 -1
- package/dist/proto/google/protobuf/duration.js.map +0 -1
- package/dist/proto/google/protobuf/empty.d.ts.map +0 -1
- package/dist/proto/google/protobuf/struct.d.ts.map +0 -1
- package/dist/proto/google/protobuf/timestamp.cjs.map +0 -1
- package/dist/proto/google/protobuf/timestamp.d.ts.map +0 -1
- package/dist/proto/google/protobuf/timestamp.js.map +0 -1
- package/dist/proto/google/protobuf/wrappers.d.ts.map +0 -1
- package/src/core/grpc.ts +0 -17
- package/src/core/http.ts +0 -178
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.ts +0 -45
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.ts +0 -313
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.ts +0 -51
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.ts +0 -406
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.ts +0 -59
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.ts +0 -489
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.ts +0 -148
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.ts +0 -719
- /package/dist/{proto → proto-grpc}/github.com/googleapis/googleapis/google/rpc/status.cjs +0 -0
- /package/dist/{proto → proto-grpc}/github.com/googleapis/googleapis/google/rpc/status.js +0 -0
- /package/dist/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/api.client.cjs +0 -0
- /package/dist/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/api.client.d.ts +0 -0
- /package/dist/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/api.client.js +0 -0
- /package/dist/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts +0 -0
- /package/dist/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/api_types.cjs +0 -0
- /package/dist/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/api_types.d.ts +0 -0
- /package/dist/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/api_types.js +0 -0
- /package/dist/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/base_types.cjs +0 -0
- /package/dist/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/base_types.d.ts +0 -0
- /package/dist/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/base_types.js +0 -0
- /package/dist/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/import.d.ts +0 -0
- /package/dist/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/resource_types.cjs +0 -0
- /package/dist/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/resource_types.d.ts +0 -0
- /package/dist/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/resource_types.js +0 -0
- /package/dist/{proto → proto-grpc}/google/protobuf/any.cjs +0 -0
- /package/dist/{proto → proto-grpc}/google/protobuf/any.d.ts +0 -0
- /package/dist/{proto → proto-grpc}/google/protobuf/any.js +0 -0
- /package/dist/{proto → proto-grpc}/google/protobuf/duration.cjs +0 -0
- /package/dist/{proto → proto-grpc}/google/protobuf/duration.d.ts +0 -0
- /package/dist/{proto → proto-grpc}/google/protobuf/duration.js +0 -0
- /package/dist/{proto → proto-grpc}/google/protobuf/empty.d.ts +0 -0
- /package/dist/{proto → proto-grpc}/google/protobuf/struct.d.ts +0 -0
- /package/dist/{proto → proto-grpc}/google/protobuf/timestamp.cjs +0 -0
- /package/dist/{proto → proto-grpc}/google/protobuf/timestamp.d.ts +0 -0
- /package/dist/{proto → proto-grpc}/google/protobuf/timestamp.js +0 -0
- /package/src/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/api.client.ts +0 -0
- /package/src/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/api_types.ts +0 -0
- /package/src/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/base_types.ts +0 -0
- /package/src/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/import.ts +0 -0
- /package/src/{proto → proto-grpc}/github.com/milaboratory/pl/plapi/plapiproto/resource_types.ts +0 -0
- /package/src/{proto → proto-grpc}/google/protobuf/any.ts +0 -0
- /package/src/{proto → proto-grpc}/google/protobuf/duration.ts +0 -0
- /package/src/{proto → proto-grpc}/google/protobuf/empty.ts +0 -0
- /package/src/{proto → proto-grpc}/google/protobuf/struct.ts +0 -0
- /package/src/{proto → proto-grpc}/google/protobuf/timestamp.ts +0 -0
package/dist/core/ll_client.js
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
|
-
import { PlatformClient } from '../proto/github.com/milaboratory/pl/plapi/plapiproto/api.client.js';
|
|
1
|
+
import { PlatformClient } from '../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.js';
|
|
2
2
|
import { compressionAlgorithms, ChannelCredentials, InterceptingCall, status } from '@grpc/grpc-js';
|
|
3
|
-
import { plAddressToConfig } from './config.js';
|
|
3
|
+
import { plAddressToConfig, SUPPORTED_WIRE_PROTOCOLS } from './config.js';
|
|
4
4
|
import { GrpcTransport } from '@protobuf-ts/grpc-transport';
|
|
5
5
|
import { LLPlTransaction } from './ll_transaction.js';
|
|
6
6
|
import { parsePlJwt } from '../util/pl.js';
|
|
7
|
+
import { interceptors } from 'undici';
|
|
7
8
|
import { inferAuthRefreshTime } from './auth.js';
|
|
8
9
|
import { defaultHttpDispatcher } from '@milaboratories/pl-http';
|
|
9
10
|
import { parseHttpAuth } from '@milaboratories/pl-model-common';
|
|
11
|
+
import { createClient, parseResponseError } from '../proto-rest/index.js';
|
|
12
|
+
import { notEmpty } from '@milaboratories/ts-helpers';
|
|
13
|
+
import { Code } from '../proto-grpc/google/rpc/code.js';
|
|
10
14
|
|
|
11
|
-
class
|
|
12
|
-
|
|
15
|
+
class WireClientProviderImpl {
|
|
16
|
+
wireOpts;
|
|
13
17
|
clientConstructor;
|
|
14
18
|
client = undefined;
|
|
15
|
-
constructor(
|
|
16
|
-
this.
|
|
19
|
+
constructor(wireOpts, clientConstructor) {
|
|
20
|
+
this.wireOpts = wireOpts;
|
|
17
21
|
this.clientConstructor = clientConstructor;
|
|
18
22
|
}
|
|
19
23
|
reset() {
|
|
@@ -21,7 +25,7 @@ class GrpcClientProviderImpl {
|
|
|
21
25
|
}
|
|
22
26
|
get() {
|
|
23
27
|
if (this.client === undefined)
|
|
24
|
-
this.client = this.clientConstructor(this.
|
|
28
|
+
this.client = this.clientConstructor(this.wireOpts());
|
|
25
29
|
return this.client;
|
|
26
30
|
}
|
|
27
31
|
}
|
|
@@ -41,44 +45,87 @@ class LLPlClient {
|
|
|
41
45
|
refreshTimestamp;
|
|
42
46
|
_status = 'OK';
|
|
43
47
|
statusListener;
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
_wireProto = undefined;
|
|
49
|
+
_wireConn;
|
|
50
|
+
_restInterceptors;
|
|
51
|
+
_restMiddlewares;
|
|
52
|
+
_grpcInterceptors;
|
|
46
53
|
providers = [];
|
|
47
|
-
|
|
54
|
+
clientProvider;
|
|
48
55
|
httpDispatcher;
|
|
49
56
|
constructor(configOrAddress, ops = {}) {
|
|
50
57
|
this.ops = ops;
|
|
51
58
|
this.conf = typeof configOrAddress === 'string'
|
|
52
59
|
? plAddressToConfig(configOrAddress)
|
|
53
60
|
: configOrAddress;
|
|
54
|
-
|
|
55
|
-
const { auth, statusListener, shouldUseGzip } = ops;
|
|
61
|
+
const { auth, statusListener } = ops;
|
|
56
62
|
if (auth !== undefined) {
|
|
57
63
|
this.refreshTimestamp = inferAuthRefreshTime(auth.authInformation, this.conf.authMaxRefreshSeconds);
|
|
58
|
-
this.grpcInterceptors.push(this.createAuthInterceptor());
|
|
59
64
|
this.authInformation = auth.authInformation;
|
|
60
65
|
this.onAuthUpdate = auth.onUpdate;
|
|
61
66
|
this.onAuthRefreshProblem = auth.onUpdateError;
|
|
62
67
|
this.onAuthError = auth.onAuthError;
|
|
63
68
|
}
|
|
64
|
-
this.
|
|
65
|
-
|
|
66
|
-
this.
|
|
69
|
+
this._restInterceptors = [];
|
|
70
|
+
this._restMiddlewares = [];
|
|
71
|
+
this._grpcInterceptors = [];
|
|
72
|
+
if (auth !== undefined) {
|
|
73
|
+
this._restInterceptors.push(this.createRestAuthInterceptor());
|
|
74
|
+
this._grpcInterceptors.push(this.createGrpcAuthInterceptor());
|
|
75
|
+
}
|
|
76
|
+
this._restInterceptors.push(interceptors.retry({ statusCodes: [] })); // Handle errors with openapi-fetch middleware.
|
|
77
|
+
this._restMiddlewares.push(this.createRestErrorMiddleware());
|
|
78
|
+
this._grpcInterceptors.push(this.createGrpcErrorInterceptor());
|
|
67
79
|
this.httpDispatcher = defaultHttpDispatcher(this.conf.httpProxy);
|
|
80
|
+
this.initWireConnection();
|
|
68
81
|
if (statusListener !== undefined) {
|
|
69
82
|
this.statusListener = statusListener;
|
|
70
83
|
statusListener(this._status);
|
|
71
84
|
}
|
|
72
|
-
this.
|
|
85
|
+
this.clientProvider = this.createWireClientProvider((wireConn) => {
|
|
86
|
+
if (wireConn.type === 'grpc') {
|
|
87
|
+
return new PlatformClient(wireConn.Transport);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
return createClient({
|
|
91
|
+
hostAndPort: wireConn.Config.hostAndPort,
|
|
92
|
+
ssl: wireConn.Config.ssl,
|
|
93
|
+
dispatcher: wireConn.Dispatcher,
|
|
94
|
+
middlewares: wireConn.Middlewares,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
initWireConnection() {
|
|
100
|
+
if (this._wireProto === undefined) {
|
|
101
|
+
// TODO: implement automatic server mode detection
|
|
102
|
+
this._wireProto = this.conf.wireProtocol ?? 'grpc';
|
|
103
|
+
}
|
|
104
|
+
switch (this._wireProto) {
|
|
105
|
+
case 'rest':
|
|
106
|
+
this.initRestConnection();
|
|
107
|
+
return;
|
|
108
|
+
case 'grpc':
|
|
109
|
+
this.initGrpcConnection(this.ops.shouldUseGzip ?? false);
|
|
110
|
+
return;
|
|
111
|
+
default:
|
|
112
|
+
((v) => {
|
|
113
|
+
throw new Error(`Unsupported wire protocol '${v}'. Use one of: ${SUPPORTED_WIRE_PROTOCOLS.join(', ')}`);
|
|
114
|
+
})(this._wireProto);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
initRestConnection() {
|
|
118
|
+
const dispatcher = defaultHttpDispatcher(this.conf.httpProxy, this._restInterceptors);
|
|
119
|
+
this._replaceWireConnection({ type: 'rest', Config: this.conf, Dispatcher: dispatcher, Middlewares: this._restMiddlewares });
|
|
73
120
|
}
|
|
74
121
|
/**
|
|
75
|
-
* Initializes (or reinitializes) _grpcTransport
|
|
122
|
+
* Initializes (or reinitializes) _grpcTransport
|
|
76
123
|
* @param gzip - whether to enable gzip compression
|
|
77
124
|
*/
|
|
78
|
-
|
|
125
|
+
initGrpcConnection(gzip) {
|
|
79
126
|
const clientOptions = {
|
|
80
127
|
'grpc.keepalive_time_ms': 30_000, // 30 seconds
|
|
81
|
-
'interceptors': this.
|
|
128
|
+
'interceptors': this._grpcInterceptors,
|
|
82
129
|
};
|
|
83
130
|
if (gzip)
|
|
84
131
|
clientOptions['grpc.default_compression_algorithm'] = compressionAlgorithms.gzip;
|
|
@@ -115,8 +162,11 @@ class LLPlClient {
|
|
|
115
162
|
else {
|
|
116
163
|
delete process.env.grpc_proxy;
|
|
117
164
|
}
|
|
118
|
-
|
|
119
|
-
|
|
165
|
+
this._replaceWireConnection({ type: 'grpc', Transport: new GrpcTransport(grpcOptions) });
|
|
166
|
+
}
|
|
167
|
+
_replaceWireConnection(newConn) {
|
|
168
|
+
const oldConn = this._wireConn;
|
|
169
|
+
this._wireConn = newConn;
|
|
120
170
|
// Reset all providers to let them reinitialize their clients
|
|
121
171
|
for (let i = 0; i < this.providers.length; i++) {
|
|
122
172
|
const provider = this.providers[i].deref();
|
|
@@ -129,8 +179,8 @@ class LLPlClient {
|
|
|
129
179
|
provider.reset();
|
|
130
180
|
}
|
|
131
181
|
}
|
|
132
|
-
if (
|
|
133
|
-
|
|
182
|
+
if (oldConn !== undefined && oldConn.type === 'grpc')
|
|
183
|
+
oldConn.Transport.close();
|
|
134
184
|
}
|
|
135
185
|
providerCleanupCounter = 0;
|
|
136
186
|
/**
|
|
@@ -138,7 +188,7 @@ class LLPlClient {
|
|
|
138
188
|
*
|
|
139
189
|
* @param clientConstructor - a factory function that creates a grpc client
|
|
140
190
|
*/
|
|
141
|
-
|
|
191
|
+
createWireClientProvider(clientConstructor) {
|
|
142
192
|
// We need to cleanup providers periodically to avoid memory leaks.
|
|
143
193
|
// This is a simple heuristic to avoid memory leaks.
|
|
144
194
|
// We could use a more sophisticated algorithm, but this is good enough for now.
|
|
@@ -153,12 +203,12 @@ class LLPlClient {
|
|
|
153
203
|
}
|
|
154
204
|
this.providerCleanupCounter = 0;
|
|
155
205
|
}
|
|
156
|
-
const provider = new
|
|
206
|
+
const provider = new WireClientProviderImpl(() => this._wireConn, clientConstructor);
|
|
157
207
|
this.providers.push(new WeakRef(provider));
|
|
158
208
|
return provider;
|
|
159
209
|
}
|
|
160
|
-
get
|
|
161
|
-
return this.
|
|
210
|
+
get wireConnection() {
|
|
211
|
+
return this._wireConn;
|
|
162
212
|
}
|
|
163
213
|
/** Returns true if client is authenticated. Even with anonymous auth information
|
|
164
214
|
* connection is considered authenticated. Unauthenticated clients are used for
|
|
@@ -200,13 +250,8 @@ class LLPlClient {
|
|
|
200
250
|
this.authRefreshInProgress = true;
|
|
201
251
|
void (async () => {
|
|
202
252
|
try {
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
seconds: BigInt(this.conf.authTTLSeconds),
|
|
206
|
-
nanos: 0,
|
|
207
|
-
},
|
|
208
|
-
}).response;
|
|
209
|
-
this.authInformation = { jwtToken: response.token };
|
|
253
|
+
const token = await this.getJwtToken(BigInt(this.conf.authTTLSeconds));
|
|
254
|
+
this.authInformation = { jwtToken: token };
|
|
210
255
|
this.refreshTimestamp = inferAuthRefreshTime(this.authInformation, this.conf.authMaxRefreshSeconds);
|
|
211
256
|
if (this.onAuthUpdate)
|
|
212
257
|
this.onAuthUpdate(this.authInformation);
|
|
@@ -220,8 +265,39 @@ class LLPlClient {
|
|
|
220
265
|
}
|
|
221
266
|
})();
|
|
222
267
|
}
|
|
223
|
-
/**
|
|
224
|
-
|
|
268
|
+
/**
|
|
269
|
+
* Creates middleware that parses error responses and handles them centrally.
|
|
270
|
+
* This middleware runs before openapi-fetch parses the response, so we need to
|
|
271
|
+
* manually parse the response body for error responses.
|
|
272
|
+
*/
|
|
273
|
+
createRestErrorMiddleware() {
|
|
274
|
+
return {
|
|
275
|
+
onResponse: async ({ request: _request, response, options: _options }) => {
|
|
276
|
+
const { body: body, ...resOptions } = response;
|
|
277
|
+
if ([502, 503, 504].includes(response.status)) {
|
|
278
|
+
// Service unavailable, bad gateway, gateway timeout
|
|
279
|
+
this.updateStatus('Disconnected');
|
|
280
|
+
return new Response(body, { ...resOptions, status: response.status });
|
|
281
|
+
}
|
|
282
|
+
const respErr = await parseResponseError(response);
|
|
283
|
+
if (!respErr.error) {
|
|
284
|
+
// No error: nice!
|
|
285
|
+
return new Response(respErr.origBody ?? body, { ...resOptions, status: response.status });
|
|
286
|
+
}
|
|
287
|
+
if (typeof respErr.error === 'string') {
|
|
288
|
+
// Non-standard error or normal response: let later middleware to deal wit it.
|
|
289
|
+
return new Response(respErr.error, { ...resOptions, status: response.status });
|
|
290
|
+
}
|
|
291
|
+
if (respErr.error.code === Code.UNAUTHENTICATED) {
|
|
292
|
+
this.updateStatus('Unauthenticated');
|
|
293
|
+
}
|
|
294
|
+
// Let later middleware to deal with standard gRPC error.
|
|
295
|
+
return new Response(respErr.origBody, { ...resOptions, status: response.status });
|
|
296
|
+
},
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
/** Detects certain errors and update client status accordingly when using GRPC wire connection */
|
|
300
|
+
createGrpcErrorInterceptor() {
|
|
225
301
|
return (options, nextCall) => {
|
|
226
302
|
return new InterceptingCall(nextCall(options), {
|
|
227
303
|
start: (metadata, listener, next) => {
|
|
@@ -240,8 +316,20 @@ class LLPlClient {
|
|
|
240
316
|
});
|
|
241
317
|
};
|
|
242
318
|
}
|
|
319
|
+
createRestAuthInterceptor() {
|
|
320
|
+
return (dispatch) => {
|
|
321
|
+
return (options, handler) => {
|
|
322
|
+
if (this.authInformation?.jwtToken !== undefined) {
|
|
323
|
+
// TODO: check this magic really works and gets called
|
|
324
|
+
options.headers = { ...options.headers, authorization: 'Bearer ' + this.authInformation.jwtToken };
|
|
325
|
+
this.refreshAuthInformationIfNeeded();
|
|
326
|
+
}
|
|
327
|
+
return dispatch(options, handler);
|
|
328
|
+
};
|
|
329
|
+
};
|
|
330
|
+
}
|
|
243
331
|
/** Injects authentication information if needed */
|
|
244
|
-
|
|
332
|
+
createGrpcAuthInterceptor() {
|
|
245
333
|
return (options, nextCall) => {
|
|
246
334
|
return new InterceptingCall(nextCall(options), {
|
|
247
335
|
start: (metadata, listener, next) => {
|
|
@@ -257,12 +345,77 @@ class LLPlClient {
|
|
|
257
345
|
});
|
|
258
346
|
};
|
|
259
347
|
}
|
|
348
|
+
async getJwtToken(ttlSeconds, options) {
|
|
349
|
+
const cl = this.clientProvider.get();
|
|
350
|
+
if (cl instanceof PlatformClient) {
|
|
351
|
+
const meta = {};
|
|
352
|
+
if (options?.authorization)
|
|
353
|
+
meta.authorization = options.authorization;
|
|
354
|
+
return (await cl.getJWTToken({ expiration: { seconds: ttlSeconds, nanos: 0 } }, { meta }).response).token;
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
const headers = {};
|
|
358
|
+
if (options?.authorization)
|
|
359
|
+
headers.authorization = options.authorization;
|
|
360
|
+
const resp = cl.POST('/v1/auth/jwt-token', {
|
|
361
|
+
body: { expiration: `${ttlSeconds}s` },
|
|
362
|
+
headers,
|
|
363
|
+
});
|
|
364
|
+
return notEmpty((await resp).data).token;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
async ping() {
|
|
368
|
+
const cl = this.clientProvider.get();
|
|
369
|
+
if (cl instanceof PlatformClient) {
|
|
370
|
+
return (await cl.ping({})).response;
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
return notEmpty((await cl.GET('/v1/ping')).data);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
async license() {
|
|
377
|
+
const cl = this.clientProvider.get();
|
|
378
|
+
if (cl instanceof PlatformClient) {
|
|
379
|
+
return (await cl.license({})).response;
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
const resp = notEmpty((await cl.GET('/v1/license')).data);
|
|
383
|
+
return {
|
|
384
|
+
status: resp.status,
|
|
385
|
+
isOk: resp.isOk,
|
|
386
|
+
responseBody: Uint8Array.from(Buffer.from(resp.responseBody)),
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
async authMethods() {
|
|
391
|
+
const cl = this.clientProvider.get();
|
|
392
|
+
if (cl instanceof PlatformClient) {
|
|
393
|
+
return (await cl.authMethods({})).response;
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
return notEmpty((await cl.GET('/v1/auth/methods')).data);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
async txSync(txId) {
|
|
400
|
+
const cl = this.clientProvider.get();
|
|
401
|
+
if (cl instanceof PlatformClient) {
|
|
402
|
+
await cl.txSync({ txId: BigInt(txId) });
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
(await cl.POST('/v1/tx-sync', { body: { txId: txId.toString() } }));
|
|
406
|
+
}
|
|
407
|
+
}
|
|
260
408
|
createTx(rw, ops = {}) {
|
|
261
409
|
return new LLPlTransaction((abortSignal) => {
|
|
262
410
|
let totalAbortSignal = abortSignal;
|
|
263
411
|
if (ops.abortSignal)
|
|
264
412
|
totalAbortSignal = AbortSignal.any([totalAbortSignal, ops.abortSignal]);
|
|
265
|
-
|
|
413
|
+
const cl = this.clientProvider.get();
|
|
414
|
+
if (!(cl instanceof PlatformClient)) {
|
|
415
|
+
// TODO: add WebSockets
|
|
416
|
+
throw new Error('tx is not supported for REST client');
|
|
417
|
+
}
|
|
418
|
+
return cl.tx({
|
|
266
419
|
abort: totalAbortSignal,
|
|
267
420
|
timeout: ops.timeout
|
|
268
421
|
?? (rw ? this.conf.defaultRWTransactionTimeout : this.conf.defaultROTransactionTimeout),
|
|
@@ -271,7 +424,9 @@ class LLPlClient {
|
|
|
271
424
|
}
|
|
272
425
|
/** Closes underlying transport */
|
|
273
426
|
async close() {
|
|
274
|
-
this.
|
|
427
|
+
if (this.wireConnection.type === 'grpc') {
|
|
428
|
+
this.wireConnection.Transport.close();
|
|
429
|
+
}
|
|
275
430
|
await this.httpDispatcher.destroy();
|
|
276
431
|
}
|
|
277
432
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ll_client.js","sources":["../../src/core/ll_client.ts"],"sourcesContent":["import { PlatformClient } from '../proto/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 } 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 } from 'undici';\nimport { inferAuthRefreshTime } from './auth';\nimport { defaultHttpDispatcher } from '@milaboratories/pl-http';\nimport type { GrpcClientProvider, GrpcClientProviderFactory } from './grpc';\nimport { parseHttpAuth } from '@milaboratories/pl-model-common';\n\nexport interface PlCallOps {\n timeout?: number;\n abortSignal?: AbortSignal;\n}\n\nclass GrpcClientProviderImpl<Client> implements GrpcClientProvider<Client> {\n private client: Client | undefined = undefined;\n\n constructor(private readonly grpcTransport: () => GrpcTransport, private readonly clientConstructor: (transport: GrpcTransport) => 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.grpcTransport());\n return this.client;\n }\n}\n\n/** Abstract out low level networking and authorization details */\nexport class LLPlClient implements GrpcClientProviderFactory {\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 readonly grpcInterceptors: Interceptor[];\n private _grpcTransport!: GrpcTransport;\n private readonly providers: WeakRef<GrpcClientProviderImpl<any>>[] = [];\n\n public readonly grpcPl: GrpcClientProvider<PlatformClient>;\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 this.grpcInterceptors = [];\n\n const { auth, statusListener, shouldUseGzip } = ops;\n\n if (auth !== undefined) {\n this.refreshTimestamp = inferAuthRefreshTime(\n auth.authInformation,\n this.conf.authMaxRefreshSeconds,\n );\n this.grpcInterceptors.push(this.createAuthInterceptor());\n this.authInformation = auth.authInformation;\n this.onAuthUpdate = auth.onUpdate;\n this.onAuthRefreshProblem = auth.onUpdateError;\n this.onAuthError = auth.onAuthError;\n }\n\n this.grpcInterceptors.push(this.createErrorInterceptor());\n\n // initialize _grpcTransport and _grpcPl\n this.initGrpc(shouldUseGzip ?? false);\n\n this.httpDispatcher = defaultHttpDispatcher(this.conf.httpProxy);\n\n if (statusListener !== undefined) {\n this.statusListener = statusListener;\n statusListener(this._status);\n }\n\n this.grpcPl = this.createGrpcClientProvider((transport) => new PlatformClient(transport));\n }\n\n /**\n * Initializes (or reinitializes) _grpcTransport and _grpcPl\n * @param gzip - whether to enable gzip compression\n */\n private initGrpc(gzip: boolean) {\n const clientOptions: ClientOptions = {\n 'grpc.keepalive_time_ms': 30_000, // 30 seconds\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 const oldTransport = this._grpcTransport;\n\n this._grpcTransport = new GrpcTransport(grpcOptions);\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 (oldTransport !== undefined) oldTransport.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 createGrpcClientProvider<Client>(clientConstructor: (transport: GrpcTransport) => Client): GrpcClientProvider<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 GrpcClientProviderImpl<Client>(() => this._grpcTransport, clientConstructor);\n this.providers.push(new WeakRef(provider));\n return provider;\n }\n\n public get grpcTransport(): GrpcTransport {\n return this._grpcTransport;\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 response = await this.grpcPl.get().getJWTToken({\n expiration: {\n seconds: BigInt(this.conf.authTTLSeconds),\n nanos: 0,\n },\n }).response;\n this.authInformation = { jwtToken: response.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 /** Detects certain errors and update client status accordingly */\n private createErrorInterceptor(): 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 /** Injects authentication information if needed */\n private createAuthInterceptor(): 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 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 return this.grpcPl.get().tx({\n abort: totalAbortSignal,\n timeout: ops.timeout\n ?? (rw ? this.conf.defaultRWTransactionTimeout : this.conf.defaultROTransactionTimeout),\n });\n });\n }\n\n /** Closes underlying transport */\n public async close() {\n this.grpcTransport.close();\n await this.httpDispatcher.destroy();\n }\n}\n"],"names":["status","GrpcStatus"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ll_client.js","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';\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 '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 cl = this.clientProvider.get();\n if (!(cl instanceof GrpcPlApiClient)) {\n // TODO: add WebSockets\n throw new Error('tx is not supported for REST client');\n }\n\n return cl.tx({\n abort: totalAbortSignal,\n timeout: ops.timeout\n ?? (rw ? this.conf.defaultRWTransactionTimeout : this.conf.defaultROTransactionTimeout),\n });\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":["GrpcPlApiClient","status","GrpcStatus"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ll_transaction.cjs","sources":["../../src/core/ll_transaction.ts"],"sourcesContent":["import type {\n TxAPI_ClientMessage,\n TxAPI_ServerMessage,\n} from '../proto/github.com/milaboratory/pl/plapi/plapiproto/api';\nimport type { DuplexStreamingCall } from '@protobuf-ts/runtime-rpc';\nimport Denque from 'denque';\nimport type { Status } from '../proto/github.com/googleapis/googleapis/google/rpc/status';\nimport {\n PlErrorCodeNotFound,\n RecoverablePlError,\n rethrowMeaningfulError,\n UnrecoverablePlError,\n} from './errors';\nimport { StatefulPromise } from './StatefulPromise';\n\nexport type ClientMessageRequest = TxAPI_ClientMessage['request'];\n\nexport type ServerMessageResponse = TxAPI_ServerMessage['response'];\n\ntype TxStream = DuplexStreamingCall<TxAPI_ClientMessage, TxAPI_ServerMessage>;\n\nexport type OneOfKind<T extends { oneofKind: unknown }, Kind extends T['oneofKind']> = Extract<\n T,\n { oneofKind: Kind }\n>;\n\ninterface SingleResponseHandler<Kind extends ServerMessageResponse['oneofKind']> {\n kind: Kind;\n expectMultiResponse: false;\n resolve: (v: OneOfKind<ServerMessageResponse, Kind>) => void;\n reject: (e: Error) => void;\n}\n\ninterface MultiResponseHandler<Kind extends ServerMessageResponse['oneofKind']> {\n kind: Kind;\n expectMultiResponse: true;\n resolve: (v: OneOfKind<ServerMessageResponse, Kind>[]) => void;\n reject: (e: Error) => void;\n}\n\ntype AnySingleResponseHandler = SingleResponseHandler<ServerMessageResponse['oneofKind']>;\n\ntype AnyMultiResponseHandler = MultiResponseHandler<ServerMessageResponse['oneofKind']>;\n\ntype AnyResponseHandler =\n | SingleResponseHandler<ServerMessageResponse['oneofKind']>\n | MultiResponseHandler<ServerMessageResponse['oneofKind']>;\n\nfunction createResponseHandler<Kind extends ServerMessageResponse['oneofKind']>(\n kind: Kind,\n expectMultiResponse: boolean,\n resolve:\n | ((v: OneOfKind<ServerMessageResponse, Kind>) => void)\n | ((v: OneOfKind<ServerMessageResponse, Kind>[]) => void),\n reject: (e: Error) => void,\n): AnyResponseHandler {\n return { kind, expectMultiResponse, resolve, reject } as AnyResponseHandler;\n}\n\nfunction isRecoverable(status: Status): boolean {\n return status.code === PlErrorCodeNotFound;\n}\n\nexport class RethrowError extends Error {\n name = 'RethrowError';\n constructor(public readonly rethrowLambda: () => never) {\n super('Rethrow error, you should never see this one.');\n }\n}\n\nexport class LLPlTransaction {\n /** Bidirectional channel through which transaction communicates with the server */\n private readonly stream: TxStream;\n\n /** Used to abort ongoing transaction stream */\n private readonly abortController = new AbortController();\n\n /** Counter of sent requests, used to calculate which future response will correspond to this request.\n * Incremented on each sent request. */\n private requestIdxCounter = 0;\n\n /** Queue from which incoming message processor takes handlers to which pass incoming messages */\n private readonly responseHandlerQueue = new Denque<AnyResponseHandler>();\n\n /** Each new resource, created by the transaction, is assigned with virtual (local) resource id, to make it possible\n * to populate its fields without awaiting actual resource id. This counter tracks those ids on client side, the\n * same way it is tracked on the server, so client can synchronously return such ids to the user. */\n private localResourceIdCounter = 0n;\n\n /** Switches to true, when this transaction closes due to normal or exceptional conditions. Prevents any new messages\n * to be sent to the stream. */\n private closed = false;\n /** Whether the outgoing stream was already closed. */\n private completed = false;\n\n /** If this transaction was terminated due to error, this is a generator to create new errors if corresponding response is required. */\n private errorFactory?: () => never;\n\n /** Timestamp when transaction was opened */\n private readonly openTimestamp = Date.now();\n\n private readonly incomingProcessorResult: Promise<(() => never) | null>;\n\n constructor(streamFactory: (abortSignal: AbortSignal) => TxStream) {\n this.stream = streamFactory(this.abortController.signal);\n\n // Starting incoming event processor\n this.incomingProcessorResult = this.incomingEventProcessor();\n }\n\n private assignErrorFactoryIfNotSet(\n errorFactory: () => never,\n reject?: (e: Error) => void,\n ): () => never {\n if (reject !== undefined) reject(new RethrowError(errorFactory));\n if (this.errorFactory) return errorFactory;\n this.errorFactory = errorFactory;\n return errorFactory;\n }\n\n private async incomingEventProcessor(): Promise<(() => never) | null> {\n /** Counter of received responses, used to check consistency of responses.\n * Increments on each received message. */\n let expectedId = -1;\n\n // defined externally to make possible to communicate any processing errors\n // to the specific request on which it happened\n let currentHandler: AnyResponseHandler | undefined = undefined;\n let responseAggregator: ServerMessageResponse[] | undefined = undefined;\n try {\n for await (const message of this.stream.responses) {\n if (currentHandler === undefined) {\n currentHandler = this.responseHandlerQueue.shift();\n\n if (currentHandler === undefined) {\n this.assignErrorFactoryIfNotSet(() => {\n throw new Error(`orphan incoming message`);\n });\n break;\n }\n\n // allocating response aggregator array\n if (currentHandler.expectMultiResponse) responseAggregator = [];\n\n expectedId++;\n }\n\n if (message.requestId !== expectedId) {\n const errorMessage = `out of order messages, ${message.requestId} !== ${expectedId}`;\n this.assignErrorFactoryIfNotSet(() => {\n throw new Error(errorMessage);\n });\n break;\n }\n\n if (message.error !== undefined) {\n const status = message.error;\n\n if (isRecoverable(status)) {\n currentHandler.reject(\n new RethrowError(() => {\n throw new RecoverablePlError(status);\n }),\n );\n currentHandler = undefined;\n\n if (message.multiMessage !== undefined && !message.multiMessage.isLast) {\n this.assignErrorFactoryIfNotSet(() => {\n throw new Error('Unexpected message sequence.');\n });\n break;\n }\n\n // We can continue to work after recoverable errors\n continue;\n } else {\n this.assignErrorFactoryIfNotSet(() => {\n throw new UnrecoverablePlError(status);\n }, currentHandler.reject);\n currentHandler = undefined;\n\n // In case of unrecoverable errors we close the transaction\n break;\n }\n }\n\n if (\n currentHandler.kind !== message.response.oneofKind\n && message?.multiMessage?.isEmpty !== true\n ) {\n const errorMessage = `inconsistent request response types: ${currentHandler.kind} !== ${message.response.oneofKind}`;\n\n this.assignErrorFactoryIfNotSet(() => {\n throw new Error(errorMessage);\n }, currentHandler.reject);\n currentHandler = undefined;\n\n break;\n }\n\n if (currentHandler.expectMultiResponse !== (message.multiMessage !== undefined)) {\n const errorMessage = `inconsistent multi state: ${currentHandler.expectMultiResponse} !== ${message.multiMessage !== undefined}`;\n\n this.assignErrorFactoryIfNotSet(() => {\n throw new Error(errorMessage);\n }, currentHandler.reject);\n currentHandler = undefined;\n\n break;\n }\n\n // <- at this point we validated everything we can at this level\n\n if (message.multiMessage !== undefined) {\n if (!message.multiMessage.isEmpty) {\n if (message.multiMessage.id !== responseAggregator!.length + 1) {\n const errorMessage = `inconsistent multi id: ${message.multiMessage.id} !== ${responseAggregator!.length + 1}`;\n\n this.assignErrorFactoryIfNotSet(() => {\n throw new Error(errorMessage);\n }, currentHandler.reject);\n currentHandler = undefined;\n\n break;\n }\n\n responseAggregator!.push(message.response);\n }\n\n if (message.multiMessage.isLast) {\n (currentHandler as AnyMultiResponseHandler).resolve(responseAggregator!);\n responseAggregator = undefined;\n currentHandler = undefined;\n }\n } else {\n (currentHandler as AnySingleResponseHandler).resolve(message.response);\n currentHandler = undefined;\n }\n }\n } catch (e: any) {\n return this.assignErrorFactoryIfNotSet(() => {\n rethrowMeaningfulError(e, true);\n }, currentHandler?.reject);\n } finally {\n await this.close();\n }\n return null;\n }\n\n /** Executed after termination of incoming message processor */\n private async close(): Promise<void> {\n if (this.closed) return;\n\n this.closed = true;\n\n // Rejecting all messages\n\n while (true) {\n const handler = this.responseHandlerQueue.shift();\n if (!handler) break;\n if (this.errorFactory) handler.reject(new RethrowError(this.errorFactory));\n else handler.reject(new Error('no reply'));\n }\n\n // closing outgoing stream\n await this.stream.requests.complete();\n }\n\n /** Forcefully close the transaction, terminate all connections and reject all pending requests */\n public abort(cause?: Error) {\n this.assignErrorFactoryIfNotSet(() => {\n throw new Error(`transaction aborted`, { cause });\n });\n this.abortController.abort(cause);\n }\n\n /** Await incoming message loop termination and throw any leftover errors if it was unsuccessful */\n public async await(): Promise<void> {\n // for those who want to understand \"why?\":\n // this way there is no hanging promise that will complete with rejection\n // until await is implicitly requested, the this.incomingProcessorResult\n // always resolves with success\n\n const processingResult = await this.incomingProcessorResult;\n if (processingResult !== null) processingResult();\n }\n\n public async send<Kind extends ClientMessageRequest['oneofKind']>(\n r: OneOfKind<ClientMessageRequest, Kind>,\n expectMultiResponse: false\n ): Promise<OneOfKind<ServerMessageResponse, Kind>>;\n public async send<Kind extends ClientMessageRequest['oneofKind']>(\n r: OneOfKind<ClientMessageRequest, Kind>,\n expectMultiResponse: true\n ): Promise<OneOfKind<ServerMessageResponse, Kind>[]>;\n /** Generate proper client message and send it to the server, and returns a promise of future response. */\n public async send<Kind extends ClientMessageRequest['oneofKind']>(\n r: OneOfKind<ClientMessageRequest, Kind>,\n expectMultiResponse: boolean,\n ): Promise<OneOfKind<ServerMessageResponse, Kind> | OneOfKind<ServerMessageResponse, Kind>[]> {\n if (this.errorFactory) return Promise.reject(new RethrowError(this.errorFactory));\n\n if (this.closed) return Promise.reject(new Error('Transaction already closed'));\n\n // Note: Promise synchronously executes a callback passed to a constructor\n const result = StatefulPromise.fromDeferredReject(new Promise<OneOfKind<ServerMessageResponse, Kind>>((resolve, reject) => {\n this.responseHandlerQueue.push(\n createResponseHandler(r.oneofKind, expectMultiResponse, resolve, reject),\n );\n }));\n\n // Awaiting message dispatch to catch any associated errors.\n // There is no hurry, we are not going to receive a response until message is sent.\n await this.stream.requests.send({\n requestId: this.requestIdxCounter++,\n request: r,\n });\n\n try {\n return await result;\n } catch (e: any) {\n if (e instanceof RethrowError) e.rethrowLambda();\n throw new Error('Error while waiting for response', { cause: e });\n }\n }\n\n private _completed = false;\n\n /** Safe to call multiple times */\n public async complete() {\n if (this._completed) return;\n this._completed = true;\n await this.stream.requests.complete();\n }\n}\n"],"names":["PlErrorCodeNotFound","RecoverablePlError","UnrecoverablePlError","rethrowMeaningfulError","StatefulPromise"],"mappings":";;;;;;AAgDA,SAAS,qBAAqB,CAC5B,IAAU,EACV,mBAA4B,EAC5B,OAE2D,EAC3D,MAA0B,EAAA;IAE1B,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,EAAwB;AAC7E;AAEA,SAAS,aAAa,CAAC,MAAc,EAAA;AACnC,IAAA,OAAO,MAAM,CAAC,IAAI,KAAKA,0BAAmB;AAC5C;AAEM,MAAO,YAAa,SAAQ,KAAK,CAAA;AAET,IAAA,aAAA;IAD5B,IAAI,GAAG,cAAc;AACrB,IAAA,WAAA,CAA4B,aAA0B,EAAA;QACpD,KAAK,CAAC,+CAA+C,CAAC;QAD5B,IAAA,CAAA,aAAa,GAAb,aAAa;IAEzC;AACD;MAEY,eAAe,CAAA;;AAET,IAAA,MAAM;;AAGN,IAAA,eAAe,GAAG,IAAI,eAAe,EAAE;AAExD;AACuC;IAC/B,iBAAiB,GAAG,CAAC;;AAGZ,IAAA,oBAAoB,GAAG,IAAI,MAAM,EAAsB;AAExE;;AAEoG;IAC5F,sBAAsB,GAAG,EAAE;AAEnC;AAC+B;IACvB,MAAM,GAAG,KAAK;;IAEd,SAAS,GAAG,KAAK;;AAGjB,IAAA,YAAY;;AAGH,IAAA,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE;AAE1B,IAAA,uBAAuB;AAExC,IAAA,WAAA,CAAY,aAAqD,EAAA;QAC/D,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;;AAGxD,QAAA,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,sBAAsB,EAAE;IAC9D;IAEQ,0BAA0B,CAChC,YAAyB,EACzB,MAA2B,EAAA;QAE3B,IAAI,MAAM,KAAK,SAAS;AAAE,YAAA,MAAM,CAAC,IAAI,YAAY,CAAC,YAAY,CAAC,CAAC;QAChE,IAAI,IAAI,CAAC,YAAY;AAAE,YAAA,OAAO,YAAY;AAC1C,QAAA,IAAI,CAAC,YAAY,GAAG,YAAY;AAChC,QAAA,OAAO,YAAY;IACrB;AAEQ,IAAA,MAAM,sBAAsB,GAAA;AAClC;AAC0C;AAC1C,QAAA,IAAI,UAAU,GAAG,EAAE;;;QAInB,IAAI,cAAc,GAAmC,SAAS;QAC9D,IAAI,kBAAkB,GAAwC,SAAS;AACvE,QAAA,IAAI;YACF,WAAW,MAAM,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE;AACjD,gBAAA,IAAI,cAAc,KAAK,SAAS,EAAE;AAChC,oBAAA,cAAc,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE;AAElD,oBAAA,IAAI,cAAc,KAAK,SAAS,EAAE;AAChC,wBAAA,IAAI,CAAC,0BAA0B,CAAC,MAAK;AACnC,4BAAA,MAAM,IAAI,KAAK,CAAC,CAAA,uBAAA,CAAyB,CAAC;AAC5C,wBAAA,CAAC,CAAC;wBACF;oBACF;;oBAGA,IAAI,cAAc,CAAC,mBAAmB;wBAAE,kBAAkB,GAAG,EAAE;AAE/D,oBAAA,UAAU,EAAE;gBACd;AAEA,gBAAA,IAAI,OAAO,CAAC,SAAS,KAAK,UAAU,EAAE;oBACpC,MAAM,YAAY,GAAG,CAAA,uBAAA,EAA0B,OAAO,CAAC,SAAS,CAAA,KAAA,EAAQ,UAAU,CAAA,CAAE;AACpF,oBAAA,IAAI,CAAC,0BAA0B,CAAC,MAAK;AACnC,wBAAA,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC;AAC/B,oBAAA,CAAC,CAAC;oBACF;gBACF;AAEA,gBAAA,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE;AAC/B,oBAAA,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK;AAE5B,oBAAA,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE;AACzB,wBAAA,cAAc,CAAC,MAAM,CACnB,IAAI,YAAY,CAAC,MAAK;AACpB,4BAAA,MAAM,IAAIC,yBAAkB,CAAC,MAAM,CAAC;wBACtC,CAAC,CAAC,CACH;wBACD,cAAc,GAAG,SAAS;AAE1B,wBAAA,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE;AACtE,4BAAA,IAAI,CAAC,0BAA0B,CAAC,MAAK;AACnC,gCAAA,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC;AACjD,4BAAA,CAAC,CAAC;4BACF;wBACF;;wBAGA;oBACF;yBAAO;AACL,wBAAA,IAAI,CAAC,0BAA0B,CAAC,MAAK;AACnC,4BAAA,MAAM,IAAIC,2BAAoB,CAAC,MAAM,CAAC;AACxC,wBAAA,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC;wBACzB,cAAc,GAAG,SAAS;;wBAG1B;oBACF;gBACF;gBAEA,IACE,cAAc,CAAC,IAAI,KAAK,OAAO,CAAC,QAAQ,CAAC;AACtC,uBAAA,OAAO,EAAE,YAAY,EAAE,OAAO,KAAK,IAAI,EAC1C;AACA,oBAAA,MAAM,YAAY,GAAG,CAAA,qCAAA,EAAwC,cAAc,CAAC,IAAI,CAAA,KAAA,EAAQ,OAAO,CAAC,QAAQ,CAAC,SAAS,EAAE;AAEpH,oBAAA,IAAI,CAAC,0BAA0B,CAAC,MAAK;AACnC,wBAAA,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC;AAC/B,oBAAA,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC;oBACzB,cAAc,GAAG,SAAS;oBAE1B;gBACF;AAEA,gBAAA,IAAI,cAAc,CAAC,mBAAmB,MAAM,OAAO,CAAC,YAAY,KAAK,SAAS,CAAC,EAAE;AAC/E,oBAAA,MAAM,YAAY,GAAG,CAAA,0BAAA,EAA6B,cAAc,CAAC,mBAAmB,CAAA,KAAA,EAAQ,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE;AAEhI,oBAAA,IAAI,CAAC,0BAA0B,CAAC,MAAK;AACnC,wBAAA,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC;AAC/B,oBAAA,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC;oBACzB,cAAc,GAAG,SAAS;oBAE1B;gBACF;;AAIA,gBAAA,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE;AACtC,oBAAA,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE;AACjC,wBAAA,IAAI,OAAO,CAAC,YAAY,CAAC,EAAE,KAAK,kBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE;AAC9D,4BAAA,MAAM,YAAY,GAAG,CAAA,uBAAA,EAA0B,OAAO,CAAC,YAAY,CAAC,EAAE,CAAA,KAAA,EAAQ,kBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE;AAE9G,4BAAA,IAAI,CAAC,0BAA0B,CAAC,MAAK;AACnC,gCAAA,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC;AAC/B,4BAAA,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC;4BACzB,cAAc,GAAG,SAAS;4BAE1B;wBACF;AAEA,wBAAA,kBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;oBAC5C;AAEA,oBAAA,IAAI,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE;AAC9B,wBAAA,cAA0C,CAAC,OAAO,CAAC,kBAAmB,CAAC;wBACxE,kBAAkB,GAAG,SAAS;wBAC9B,cAAc,GAAG,SAAS;oBAC5B;gBACF;qBAAO;AACJ,oBAAA,cAA2C,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC;oBACtE,cAAc,GAAG,SAAS;gBAC5B;YACF;QACF;QAAE,OAAO,CAAM,EAAE;AACf,YAAA,OAAO,IAAI,CAAC,0BAA0B,CAAC,MAAK;AAC1C,gBAAAC,6BAAsB,CAAC,CAAC,EAAE,IAAI,CAAC;AACjC,YAAA,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC;QAC5B;gBAAU;AACR,YAAA,MAAM,IAAI,CAAC,KAAK,EAAE;QACpB;AACA,QAAA,OAAO,IAAI;IACb;;AAGQ,IAAA,MAAM,KAAK,GAAA;QACjB,IAAI,IAAI,CAAC,MAAM;YAAE;AAEjB,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI;;QAIlB,OAAO,IAAI,EAAE;YACX,MAAM,OAAO,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE;AACjD,YAAA,IAAI,CAAC,OAAO;gBAAE;YACd,IAAI,IAAI,CAAC,YAAY;gBAAE,OAAO,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;;gBACrE,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;QAC5C;;QAGA,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE;IACvC;;AAGO,IAAA,KAAK,CAAC,KAAa,EAAA;AACxB,QAAA,IAAI,CAAC,0BAA0B,CAAC,MAAK;YACnC,MAAM,IAAI,KAAK,CAAC,CAAA,mBAAA,CAAqB,EAAE,EAAE,KAAK,EAAE,CAAC;AACnD,QAAA,CAAC,CAAC;AACF,QAAA,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC;IACnC;;AAGO,IAAA,MAAM,KAAK,GAAA;;;;;AAMhB,QAAA,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,uBAAuB;QAC3D,IAAI,gBAAgB,KAAK,IAAI;AAAE,YAAA,gBAAgB,EAAE;IACnD;;AAWO,IAAA,MAAM,IAAI,CACf,CAAwC,EACxC,mBAA4B,EAAA;QAE5B,IAAI,IAAI,CAAC,YAAY;AAAE,YAAA,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAEjF,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;;AAG/E,QAAA,MAAM,MAAM,GAAGC,+BAAe,CAAC,kBAAkB,CAAC,IAAI,OAAO,CAAyC,CAAC,OAAO,EAAE,MAAM,KAAI;AACxH,YAAA,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAC5B,qBAAqB,CAAC,CAAC,CAAC,SAAS,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,CAAC,CACzE;QACH,CAAC,CAAC,CAAC;;;AAIH,QAAA,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC9B,YAAA,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE;AACnC,YAAA,OAAO,EAAE,CAAC;AACX,SAAA,CAAC;AAEF,QAAA,IAAI;YACF,OAAO,MAAM,MAAM;QACrB;QAAE,OAAO,CAAM,EAAE;YACf,IAAI,CAAC,YAAY,YAAY;gBAAE,CAAC,CAAC,aAAa,EAAE;YAChD,MAAM,IAAI,KAAK,CAAC,kCAAkC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACnE;IACF;IAEQ,UAAU,GAAG,KAAK;;AAGnB,IAAA,MAAM,QAAQ,GAAA;QACnB,IAAI,IAAI,CAAC,UAAU;YAAE;AACrB,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI;QACtB,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE;IACvC;AACD;;;;;"}
|
|
1
|
+
{"version":3,"file":"ll_transaction.cjs","sources":["../../src/core/ll_transaction.ts"],"sourcesContent":["import type {\n TxAPI_ClientMessage,\n TxAPI_ServerMessage,\n} from '../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api';\nimport type { BiDiStream } from './abstract_stream';\nimport Denque from 'denque';\nimport type { Status } from '../proto-grpc/github.com/googleapis/googleapis/google/rpc/status';\nimport {\n PlErrorCodeNotFound,\n RecoverablePlError,\n rethrowMeaningfulError,\n UnrecoverablePlError,\n} from './errors';\nimport { StatefulPromise } from './StatefulPromise';\n\nexport type ClientMessageRequest = TxAPI_ClientMessage['request'];\n\nexport type ServerMessageResponse = TxAPI_ServerMessage['response'];\n\ntype TxStream = BiDiStream<TxAPI_ClientMessage, TxAPI_ServerMessage>;\n\nexport type OneOfKind<T extends { oneofKind: unknown }, Kind extends T['oneofKind']> = Extract<\n T,\n { oneofKind: Kind }\n>;\n\ninterface SingleResponseHandler<Kind extends ServerMessageResponse['oneofKind']> {\n kind: Kind;\n expectMultiResponse: false;\n resolve: (v: OneOfKind<ServerMessageResponse, Kind>) => void;\n reject: (e: Error) => void;\n}\n\ninterface MultiResponseHandler<Kind extends ServerMessageResponse['oneofKind']> {\n kind: Kind;\n expectMultiResponse: true;\n resolve: (v: OneOfKind<ServerMessageResponse, Kind>[]) => void;\n reject: (e: Error) => void;\n}\n\ntype AnySingleResponseHandler = SingleResponseHandler<ServerMessageResponse['oneofKind']>;\n\ntype AnyMultiResponseHandler = MultiResponseHandler<ServerMessageResponse['oneofKind']>;\n\ntype AnyResponseHandler =\n | SingleResponseHandler<ServerMessageResponse['oneofKind']>\n | MultiResponseHandler<ServerMessageResponse['oneofKind']>;\n\nfunction createResponseHandler<Kind extends ServerMessageResponse['oneofKind']>(\n kind: Kind,\n expectMultiResponse: boolean,\n resolve:\n | ((v: OneOfKind<ServerMessageResponse, Kind>) => void)\n | ((v: OneOfKind<ServerMessageResponse, Kind>[]) => void),\n reject: (e: Error) => void,\n): AnyResponseHandler {\n return { kind, expectMultiResponse, resolve, reject } as AnyResponseHandler;\n}\n\nfunction isRecoverable(status: Status): boolean {\n return status.code === PlErrorCodeNotFound;\n}\n\nexport class RethrowError extends Error {\n name = 'RethrowError';\n constructor(public readonly rethrowLambda: () => never) {\n super('Rethrow error, you should never see this one.');\n }\n}\n\nexport class LLPlTransaction {\n /** Bidirectional channel through which transaction communicates with the server */\n private readonly stream: TxStream;\n\n /** Used to abort ongoing transaction stream */\n private readonly abortController = new AbortController();\n\n /** Counter of sent requests, used to calculate which future response will correspond to this request.\n * Incremented on each sent request. */\n private requestIdxCounter = 0;\n\n /** Queue from which incoming message processor takes handlers to which pass incoming messages */\n private readonly responseHandlerQueue = new Denque<AnyResponseHandler>();\n\n /** Each new resource, created by the transaction, is assigned with virtual (local) resource id, to make it possible\n * to populate its fields without awaiting actual resource id. This counter tracks those ids on client side, the\n * same way it is tracked on the server, so client can synchronously return such ids to the user. */\n private localResourceIdCounter = 0n;\n\n /** Switches to true, when this transaction closes due to normal or exceptional conditions. Prevents any new messages\n * to be sent to the stream. */\n private closed = false;\n /** Whether the outgoing stream was already closed. */\n private completed = false;\n\n /** If this transaction was terminated due to error, this is a generator to create new errors if corresponding response is required. */\n private errorFactory?: () => never;\n\n /** Timestamp when transaction was opened */\n private readonly openTimestamp = Date.now();\n\n private readonly incomingProcessorResult: Promise<(() => never) | null>;\n\n constructor(streamFactory: (abortSignal: AbortSignal) => TxStream) {\n this.stream = streamFactory(this.abortController.signal);\n\n // Starting incoming event processor\n this.incomingProcessorResult = this.incomingEventProcessor();\n }\n\n private assignErrorFactoryIfNotSet(\n errorFactory: () => never,\n reject?: (e: Error) => void,\n ): () => never {\n if (reject !== undefined) reject(new RethrowError(errorFactory));\n if (this.errorFactory) return errorFactory;\n this.errorFactory = errorFactory;\n return errorFactory;\n }\n\n private async incomingEventProcessor(): Promise<(() => never) | null> {\n /** Counter of received responses, used to check consistency of responses.\n * Increments on each received message. */\n let expectedId = -1;\n\n // defined externally to make possible to communicate any processing errors\n // to the specific request on which it happened\n let currentHandler: AnyResponseHandler | undefined = undefined;\n let responseAggregator: ServerMessageResponse[] | undefined = undefined;\n try {\n for await (const message of this.stream.responses) {\n if (currentHandler === undefined) {\n currentHandler = this.responseHandlerQueue.shift();\n\n if (currentHandler === undefined) {\n this.assignErrorFactoryIfNotSet(() => {\n throw new Error(`orphan incoming message`);\n });\n break;\n }\n\n // allocating response aggregator array\n if (currentHandler.expectMultiResponse) responseAggregator = [];\n\n expectedId++;\n }\n\n if (message.requestId !== expectedId) {\n const errorMessage = `out of order messages, ${message.requestId} !== ${expectedId}`;\n this.assignErrorFactoryIfNotSet(() => {\n throw new Error(errorMessage);\n });\n break;\n }\n\n if (message.error !== undefined) {\n const status = message.error;\n\n if (isRecoverable(status)) {\n currentHandler.reject(\n new RethrowError(() => {\n throw new RecoverablePlError(status);\n }),\n );\n currentHandler = undefined;\n\n if (message.multiMessage !== undefined && !message.multiMessage.isLast) {\n this.assignErrorFactoryIfNotSet(() => {\n throw new Error('Unexpected message sequence.');\n });\n break;\n }\n\n // We can continue to work after recoverable errors\n continue;\n } else {\n this.assignErrorFactoryIfNotSet(() => {\n throw new UnrecoverablePlError(status);\n }, currentHandler.reject);\n currentHandler = undefined;\n\n // In case of unrecoverable errors we close the transaction\n break;\n }\n }\n\n if (\n currentHandler.kind !== message.response.oneofKind\n && message?.multiMessage?.isEmpty !== true\n ) {\n const errorMessage = `inconsistent request response types: ${currentHandler.kind} !== ${message.response.oneofKind}`;\n\n this.assignErrorFactoryIfNotSet(() => {\n throw new Error(errorMessage);\n }, currentHandler.reject);\n currentHandler = undefined;\n\n break;\n }\n\n if (currentHandler.expectMultiResponse !== (message.multiMessage !== undefined)) {\n const errorMessage = `inconsistent multi state: ${currentHandler.expectMultiResponse} !== ${message.multiMessage !== undefined}`;\n\n this.assignErrorFactoryIfNotSet(() => {\n throw new Error(errorMessage);\n }, currentHandler.reject);\n currentHandler = undefined;\n\n break;\n }\n\n // <- at this point we validated everything we can at this level\n\n if (message.multiMessage !== undefined) {\n if (!message.multiMessage.isEmpty) {\n if (message.multiMessage.id !== responseAggregator!.length + 1) {\n const errorMessage = `inconsistent multi id: ${message.multiMessage.id} !== ${responseAggregator!.length + 1}`;\n\n this.assignErrorFactoryIfNotSet(() => {\n throw new Error(errorMessage);\n }, currentHandler.reject);\n currentHandler = undefined;\n\n break;\n }\n\n responseAggregator!.push(message.response);\n }\n\n if (message.multiMessage.isLast) {\n (currentHandler as AnyMultiResponseHandler).resolve(responseAggregator!);\n responseAggregator = undefined;\n currentHandler = undefined;\n }\n } else {\n (currentHandler as AnySingleResponseHandler).resolve(message.response);\n currentHandler = undefined;\n }\n }\n } catch (e: any) {\n return this.assignErrorFactoryIfNotSet(() => {\n rethrowMeaningfulError(e, true);\n }, currentHandler?.reject);\n } finally {\n await this.close();\n }\n return null;\n }\n\n /** Executed after termination of incoming message processor */\n private async close(): Promise<void> {\n if (this.closed) return;\n\n this.closed = true;\n\n // Rejecting all messages\n\n while (true) {\n const handler = this.responseHandlerQueue.shift();\n if (!handler) break;\n if (this.errorFactory) handler.reject(new RethrowError(this.errorFactory));\n else handler.reject(new Error('no reply'));\n }\n\n // closing outgoing stream\n await this.stream.requests.complete();\n }\n\n /** Forcefully close the transaction, terminate all connections and reject all pending requests */\n public abort(cause?: Error) {\n this.assignErrorFactoryIfNotSet(() => {\n throw new Error(`transaction aborted`, { cause });\n });\n this.abortController.abort(cause);\n }\n\n /** Await incoming message loop termination and throw any leftover errors if it was unsuccessful */\n public async await(): Promise<void> {\n // for those who want to understand \"why?\":\n // this way there is no hanging promise that will complete with rejection\n // until await is implicitly requested, the this.incomingProcessorResult\n // always resolves with success\n\n const processingResult = await this.incomingProcessorResult;\n if (processingResult !== null) processingResult();\n }\n\n public async send<Kind extends ClientMessageRequest['oneofKind']>(\n r: OneOfKind<ClientMessageRequest, Kind>,\n expectMultiResponse: false\n ): Promise<OneOfKind<ServerMessageResponse, Kind>>;\n public async send<Kind extends ClientMessageRequest['oneofKind']>(\n r: OneOfKind<ClientMessageRequest, Kind>,\n expectMultiResponse: true\n ): Promise<OneOfKind<ServerMessageResponse, Kind>[]>;\n /** Generate proper client message and send it to the server, and returns a promise of future response. */\n public async send<Kind extends ClientMessageRequest['oneofKind']>(\n r: OneOfKind<ClientMessageRequest, Kind>,\n expectMultiResponse: boolean,\n ): Promise<OneOfKind<ServerMessageResponse, Kind> | OneOfKind<ServerMessageResponse, Kind>[]> {\n if (this.errorFactory) return Promise.reject(new RethrowError(this.errorFactory));\n\n if (this.closed) return Promise.reject(new Error('Transaction already closed'));\n\n // Note: Promise synchronously executes a callback passed to a constructor\n const result = StatefulPromise.fromDeferredReject(new Promise<OneOfKind<ServerMessageResponse, Kind>>((resolve, reject) => {\n this.responseHandlerQueue.push(\n createResponseHandler(r.oneofKind, expectMultiResponse, resolve, reject),\n );\n }));\n\n // Awaiting message dispatch to catch any associated errors.\n // There is no hurry, we are not going to receive a response until message is sent.\n await this.stream.requests.send({\n requestId: this.requestIdxCounter++,\n request: r,\n });\n\n try {\n return await result;\n } catch (e: any) {\n if (e instanceof RethrowError) e.rethrowLambda();\n throw new Error('Error while waiting for response', { cause: e });\n }\n }\n\n private _completed = false;\n\n /** Safe to call multiple times */\n public async complete() {\n if (this._completed) return;\n this._completed = true;\n await this.stream.requests.complete();\n }\n}\n"],"names":["PlErrorCodeNotFound","RecoverablePlError","UnrecoverablePlError","rethrowMeaningfulError","StatefulPromise"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { TxAPI_ClientMessage, TxAPI_ServerMessage } from '../proto/github.com/milaboratory/pl/plapi/plapiproto/api';
|
|
2
|
-
import type {
|
|
1
|
+
import type { TxAPI_ClientMessage, TxAPI_ServerMessage } from '../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api';
|
|
2
|
+
import type { BiDiStream } from './abstract_stream';
|
|
3
3
|
export type ClientMessageRequest = TxAPI_ClientMessage['request'];
|
|
4
4
|
export type ServerMessageResponse = TxAPI_ServerMessage['response'];
|
|
5
|
-
type TxStream =
|
|
5
|
+
type TxStream = BiDiStream<TxAPI_ClientMessage, TxAPI_ServerMessage>;
|
|
6
6
|
export type OneOfKind<T extends {
|
|
7
7
|
oneofKind: unknown;
|
|
8
8
|
}, Kind extends T['oneofKind']> = Extract<T, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ll_transaction.d.ts","sourceRoot":"","sources":["../../src/core/ll_transaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,
|
|
1
|
+
{"version":3,"file":"ll_transaction.d.ts","sourceRoot":"","sources":["../../src/core/ll_transaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,+DAA+D,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAWpD,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;AAElE,MAAM,MAAM,qBAAqB,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;AAEpE,KAAK,QAAQ,GAAG,UAAU,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAAC;AAErE,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,EAAE,IAAI,SAAS,CAAC,CAAC,WAAW,CAAC,IAAI,OAAO,CAC5F,CAAC,EACD;IAAE,SAAS,EAAE,IAAI,CAAA;CAAE,CACpB,CAAC;AAuCF,qBAAa,YAAa,SAAQ,KAAK;aAET,aAAa,EAAE,MAAM,KAAK;IADtD,IAAI,SAAkB;gBACM,aAAa,EAAE,MAAM,KAAK;CAGvD;AAED,qBAAa,eAAe;IAC1B,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAW;IAElC,+CAA+C;IAC/C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAyB;IAEzD;2CACuC;IACvC,OAAO,CAAC,iBAAiB,CAAK;IAE9B,iGAAiG;IACjG,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAoC;IAEzE;;wGAEoG;IACpG,OAAO,CAAC,sBAAsB,CAAM;IAEpC;mCAC+B;IAC/B,OAAO,CAAC,MAAM,CAAS;IACvB,sDAAsD;IACtD,OAAO,CAAC,SAAS,CAAS;IAE1B,uIAAuI;IACvI,OAAO,CAAC,YAAY,CAAC,CAAc;IAEnC,4CAA4C;IAC5C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAc;IAE5C,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAgC;gBAE5D,aAAa,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,QAAQ;IAOjE,OAAO,CAAC,0BAA0B;YAUpB,sBAAsB;IAiIpC,+DAA+D;YACjD,KAAK;IAkBnB,kGAAkG;IAC3F,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK;IAO1B,mGAAmG;IACtF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAUtB,IAAI,CAAC,IAAI,SAAS,oBAAoB,CAAC,WAAW,CAAC,EAC9D,CAAC,EAAE,SAAS,CAAC,oBAAoB,EAAE,IAAI,CAAC,EACxC,mBAAmB,EAAE,KAAK,GACzB,OAAO,CAAC,SAAS,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,IAAI,SAAS,oBAAoB,CAAC,WAAW,CAAC,EAC9D,CAAC,EAAE,SAAS,CAAC,oBAAoB,EAAE,IAAI,CAAC,EACxC,mBAAmB,EAAE,IAAI,GACxB,OAAO,CAAC,SAAS,CAAC,qBAAqB,EAAE,IAAI,CAAC,EAAE,CAAC;IAgCpD,OAAO,CAAC,UAAU,CAAS;IAE3B,kCAAkC;IACrB,QAAQ;CAKtB"}
|