@milaboratories/pl-client 2.16.26 → 2.16.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/core/PromiseTracker.cjs +1 -3
- package/dist/core/PromiseTracker.cjs.map +1 -1
- package/dist/core/PromiseTracker.d.ts.map +1 -1
- package/dist/core/PromiseTracker.js +1 -3
- package/dist/core/PromiseTracker.js.map +1 -1
- package/dist/core/StatefulPromise.cjs +4 -4
- package/dist/core/StatefulPromise.cjs.map +1 -1
- package/dist/core/StatefulPromise.d.ts +1 -1
- package/dist/core/StatefulPromise.d.ts.map +1 -1
- package/dist/core/StatefulPromise.js +4 -4
- package/dist/core/StatefulPromise.js.map +1 -1
- package/dist/core/advisory_locks.cjs +1 -1
- package/dist/core/advisory_locks.cjs.map +1 -1
- package/dist/core/advisory_locks.js +1 -1
- package/dist/core/advisory_locks.js.map +1 -1
- package/dist/core/auth.cjs.map +1 -1
- package/dist/core/auth.d.ts +1 -1
- package/dist/core/auth.js.map +1 -1
- package/dist/core/cache.d.ts +1 -1
- package/dist/core/client.cjs +14 -14
- package/dist/core/client.cjs.map +1 -1
- package/dist/core/client.d.ts +11 -11
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +14 -14
- package/dist/core/client.js.map +1 -1
- package/dist/core/config.cjs +39 -39
- package/dist/core/config.cjs.map +1 -1
- package/dist/core/config.d.ts +5 -5
- package/dist/core/config.js +39 -39
- package/dist/core/config.js.map +1 -1
- package/dist/core/default_client.cjs +23 -23
- package/dist/core/default_client.cjs.map +1 -1
- package/dist/core/default_client.d.ts +3 -3
- package/dist/core/default_client.js +23 -23
- package/dist/core/default_client.js.map +1 -1
- package/dist/core/driver.cjs +1 -1
- package/dist/core/driver.cjs.map +1 -1
- package/dist/core/driver.d.ts +5 -5
- package/dist/core/driver.js +1 -1
- package/dist/core/driver.js.map +1 -1
- package/dist/core/error_resource.cjs +2 -2
- package/dist/core/error_resource.cjs.map +1 -1
- package/dist/core/error_resource.d.ts +1 -1
- package/dist/core/error_resource.js +2 -2
- package/dist/core/error_resource.js.map +1 -1
- package/dist/core/errors.cjs +24 -24
- 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 +24 -24
- package/dist/core/errors.js.map +1 -1
- package/dist/core/final.cjs +43 -43
- package/dist/core/final.cjs.map +1 -1
- package/dist/core/final.d.ts +3 -3
- package/dist/core/final.d.ts.map +1 -1
- package/dist/core/final.js +43 -43
- package/dist/core/final.js.map +1 -1
- package/dist/core/ll_client.cjs +50 -43
- package/dist/core/ll_client.cjs.map +1 -1
- package/dist/core/ll_client.d.ts +9 -9
- package/dist/core/ll_client.d.ts.map +1 -1
- package/dist/core/ll_client.js +50 -43
- package/dist/core/ll_client.js.map +1 -1
- package/dist/core/ll_transaction.cjs +9 -9
- package/dist/core/ll_transaction.cjs.map +1 -1
- package/dist/core/ll_transaction.d.ts +7 -7
- package/dist/core/ll_transaction.d.ts.map +1 -1
- package/dist/core/ll_transaction.js +9 -9
- package/dist/core/ll_transaction.js.map +1 -1
- package/dist/core/stat.cjs.map +1 -1
- package/dist/core/stat.d.ts +1 -1
- package/dist/core/stat.js.map +1 -1
- package/dist/core/transaction.cjs +46 -46
- package/dist/core/transaction.cjs.map +1 -1
- package/dist/core/transaction.d.ts +7 -7
- package/dist/core/transaction.d.ts.map +1 -1
- package/dist/core/transaction.js +46 -46
- package/dist/core/transaction.js.map +1 -1
- package/dist/core/type_conversion.cjs +22 -22
- package/dist/core/type_conversion.cjs.map +1 -1
- package/dist/core/type_conversion.d.ts +3 -3
- package/dist/core/type_conversion.d.ts.map +1 -1
- package/dist/core/type_conversion.js +22 -22
- package/dist/core/type_conversion.js.map +1 -1
- package/dist/core/types.cjs +25 -25
- package/dist/core/types.cjs.map +1 -1
- package/dist/core/types.d.ts +7 -7
- package/dist/core/types.js +25 -25
- package/dist/core/types.js.map +1 -1
- package/dist/core/unauth_client.cjs +6 -4
- package/dist/core/unauth_client.cjs.map +1 -1
- package/dist/core/unauth_client.d.ts +4 -4
- package/dist/core/unauth_client.d.ts.map +1 -1
- package/dist/core/unauth_client.js +6 -4
- package/dist/core/unauth_client.js.map +1 -1
- package/dist/core/websocket_stream.cjs +22 -20
- package/dist/core/websocket_stream.cjs.map +1 -1
- package/dist/core/websocket_stream.d.ts +3 -3
- package/dist/core/websocket_stream.d.ts.map +1 -1
- package/dist/core/websocket_stream.js +22 -20
- package/dist/core/websocket_stream.js.map +1 -1
- package/dist/core/wire.d.ts +6 -6
- package/dist/core/wire.d.ts.map +1 -1
- package/dist/helpers/pl.cjs +19 -19
- package/dist/helpers/pl.cjs.map +1 -1
- package/dist/helpers/pl.d.ts +2 -2
- package/dist/helpers/pl.js +19 -19
- package/dist/helpers/pl.js.map +1 -1
- package/dist/helpers/poll.cjs +6 -6
- package/dist/helpers/poll.cjs.map +1 -1
- package/dist/helpers/poll.d.ts +4 -4
- package/dist/helpers/poll.d.ts.map +1 -1
- package/dist/helpers/poll.js +6 -6
- package/dist/helpers/poll.js.map +1 -1
- package/dist/helpers/retry_strategy.cjs +1 -1
- package/dist/helpers/retry_strategy.cjs.map +1 -1
- package/dist/helpers/retry_strategy.d.ts.map +1 -1
- package/dist/helpers/retry_strategy.js +1 -1
- package/dist/helpers/retry_strategy.js.map +1 -1
- package/dist/helpers/state_helpers.d.ts +2 -2
- package/dist/helpers/tx_helpers.cjs +2 -2
- package/dist/helpers/tx_helpers.cjs.map +1 -1
- package/dist/helpers/tx_helpers.d.ts +2 -2
- package/dist/helpers/tx_helpers.d.ts.map +1 -1
- package/dist/helpers/tx_helpers.js +2 -2
- package/dist/helpers/tx_helpers.js.map +1 -1
- package/dist/index.d.ts +16 -16
- package/dist/proto-grpc/google/protobuf/struct.d.ts +1 -1
- package/dist/proto-grpc/google/protobuf/struct.d.ts.map +1 -1
- package/dist/proto-rest/index.cjs +4 -5
- package/dist/proto-rest/index.cjs.map +1 -1
- package/dist/proto-rest/index.d.ts +4 -4
- package/dist/proto-rest/index.d.ts.map +1 -1
- package/dist/proto-rest/index.js +4 -5
- package/dist/proto-rest/index.js.map +1 -1
- package/dist/proto-rest/plapi.d.ts.map +1 -1
- package/dist/test/tcp-proxy.cjs +11 -10
- package/dist/test/tcp-proxy.cjs.map +1 -1
- package/dist/test/tcp-proxy.d.ts +1 -1
- package/dist/test/tcp-proxy.d.ts.map +1 -1
- package/dist/test/tcp-proxy.js +11 -10
- package/dist/test/tcp-proxy.js.map +1 -1
- package/dist/test/test_config.cjs +21 -17
- package/dist/test/test_config.cjs.map +1 -1
- package/dist/test/test_config.d.ts +6 -6
- package/dist/test/test_config.d.ts.map +1 -1
- package/dist/test/test_config.js +21 -17
- package/dist/test/test_config.js.map +1 -1
- package/dist/util/pl.cjs +1 -1
- package/dist/util/pl.cjs.map +1 -1
- package/dist/util/pl.js +1 -1
- package/dist/util/pl.js.map +1 -1
- package/dist/util/util.cjs +1 -1
- package/dist/util/util.cjs.map +1 -1
- package/dist/util/util.js +1 -1
- package/dist/util/util.js.map +1 -1
- package/package.json +23 -23
- package/src/core/PromiseTracker.ts +3 -4
- package/src/core/StatefulPromise.ts +17 -8
- package/src/core/abstract_stream.ts +3 -4
- package/src/core/advisory_locks.ts +1 -1
- package/src/core/auth.ts +2 -2
- package/src/core/cache.ts +1 -1
- package/src/core/client.test.ts +25 -21
- package/src/core/client.ts +54 -45
- package/src/core/config.test.ts +44 -44
- package/src/core/config.ts +49 -49
- package/src/core/connectivity.test.ts +69 -63
- package/src/core/default_client.ts +46 -46
- package/src/core/driver.ts +6 -6
- package/src/core/error.test.ts +5 -5
- package/src/core/error_resource.ts +3 -3
- package/src/core/errors.ts +39 -31
- package/src/core/final.ts +48 -55
- package/src/core/ll_client.test.ts +53 -36
- package/src/core/ll_client.ts +125 -81
- package/src/core/ll_transaction.test.ts +75 -49
- package/src/core/ll_transaction.ts +37 -35
- package/src/core/stat.ts +1 -1
- package/src/core/transaction.test.ts +65 -65
- package/src/core/transaction.ts +91 -84
- package/src/core/type_conversion.ts +30 -31
- package/src/core/types.test.ts +6 -6
- package/src/core/types.ts +35 -35
- package/src/core/unauth_client.test.ts +18 -14
- package/src/core/unauth_client.ts +14 -12
- package/src/core/websocket_stream.test.ts +52 -52
- package/src/core/websocket_stream.ts +41 -37
- package/src/core/wire.ts +10 -8
- package/src/helpers/pl.ts +22 -22
- package/src/helpers/poll.ts +13 -27
- package/src/helpers/retry_strategy.ts +2 -4
- package/src/helpers/rich_resource_types.test.ts +2 -2
- package/src/helpers/state_helpers.ts +3 -3
- package/src/helpers/tx_helpers.ts +9 -7
- package/src/index.ts +16 -16
- package/src/proto-grpc/google/protobuf/struct.ts +1 -1
- package/src/proto-rest/index.ts +17 -18
- package/src/proto-rest/plapi.ts +1472 -1472
- package/src/test/tcp-proxy.ts +55 -54
- package/src/test/test_config.test.ts +3 -3
- package/src/test/test_config.ts +51 -46
- package/src/util/pl.ts +1 -1
- package/src/util/util.test.ts +5 -5
- package/src/util/util.ts +1 -1
- package/dist/helpers/rich_resource_types.d.ts +0 -2
- package/dist/helpers/rich_resource_types.d.ts.map +0 -1
- package/dist/helpers/smart_accessors.d.ts +0 -2
- package/dist/helpers/smart_accessors.d.ts.map +0 -1
- package/src/helpers/rich_resource_types.ts +0 -84
- package/src/helpers/smart_accessors.ts +0 -146
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type PromiseState =
|
|
1
|
+
type PromiseState = "pending" | "fulfilled" | "rejected";
|
|
2
2
|
|
|
3
3
|
type StatefulPromiseOptions<T> = {
|
|
4
4
|
/**
|
|
@@ -30,32 +30,41 @@ export class StatefulPromise<T> implements Promise<T> {
|
|
|
30
30
|
return new StatefulPromise(promise, options);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
static fromDeferredReject<T>(
|
|
33
|
+
static fromDeferredReject<T>(
|
|
34
|
+
promise: Promise<T>,
|
|
35
|
+
onUnwrap?: (promise: StatefulPromise<T>) => void,
|
|
36
|
+
): StatefulPromise<T> {
|
|
34
37
|
return new StatefulPromise(promise, { deferReject: true, onUnwrap });
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
static fromDeferredRejectCallback<T>(
|
|
40
|
+
static fromDeferredRejectCallback<T>(
|
|
41
|
+
asyncFn: () => Promise<T>,
|
|
42
|
+
onUnwrap?: (promise: StatefulPromise<T>) => void,
|
|
43
|
+
): StatefulPromise<T> {
|
|
38
44
|
return new StatefulPromise(asyncFn(), { deferReject: true, onUnwrap });
|
|
39
45
|
}
|
|
40
46
|
|
|
41
|
-
private constructor(
|
|
42
|
-
|
|
47
|
+
private constructor(
|
|
48
|
+
private readonly promise: Promise<T>,
|
|
49
|
+
private readonly options: StatefulPromiseOptions<T> = {},
|
|
50
|
+
) {
|
|
51
|
+
this._state = "pending";
|
|
43
52
|
this._id = StatefulPromise.idCounter++;
|
|
44
53
|
|
|
45
54
|
this.promise
|
|
46
55
|
.then((value) => {
|
|
47
|
-
this._state =
|
|
56
|
+
this._state = "fulfilled";
|
|
48
57
|
return value;
|
|
49
58
|
})
|
|
50
59
|
.catch((err) => {
|
|
51
|
-
this._state =
|
|
60
|
+
this._state = "rejected";
|
|
52
61
|
if (!options.deferReject) {
|
|
53
62
|
throw err;
|
|
54
63
|
}
|
|
55
64
|
});
|
|
56
65
|
}
|
|
57
66
|
|
|
58
|
-
readonly [Symbol.toStringTag] =
|
|
67
|
+
readonly [Symbol.toStringTag] = "Promise";
|
|
59
68
|
|
|
60
69
|
get id(): bigint {
|
|
61
70
|
return this._id;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DuplexStreamingCall } from
|
|
1
|
+
import type { DuplexStreamingCall } from "@protobuf-ts/runtime-rpc";
|
|
2
2
|
|
|
3
3
|
export interface RequestsStream<T> {
|
|
4
4
|
/**
|
|
@@ -20,6 +20,5 @@ export interface BiDiStream<I extends object, O extends object> {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
// Compile-time type compatibility check: BiDiStream is compatible with DuplexStreamingCall implementaions.
|
|
23
|
-
type _CompatibilityTest<I extends object, O extends object> =
|
|
24
|
-
? true
|
|
25
|
-
: never;
|
|
23
|
+
type _CompatibilityTest<I extends object, O extends object> =
|
|
24
|
+
DuplexStreamingCall<I, O> extends BiDiStream<I, O> ? true : never;
|
package/src/core/auth.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { AuthInformation } from
|
|
2
|
-
import { parsePlJwt } from
|
|
1
|
+
import type { AuthInformation } from "./config";
|
|
2
|
+
import { parsePlJwt } from "../util/pl";
|
|
3
3
|
|
|
4
4
|
/** Returns a timestamp when current authorization information should be refreshed.
|
|
5
5
|
* Compare the value with Date.now(). */
|
package/src/core/cache.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BasicResourceData, ResourceData } from
|
|
1
|
+
import type { BasicResourceData, ResourceData } from "./types";
|
|
2
2
|
|
|
3
3
|
export type ResourceDataCacheRecord = {
|
|
4
4
|
/** There is a slight chance of inconsistent data retrieval from tx if we allow later transactions to leak resource data into earlier transactions.
|
package/src/core/client.test.ts
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { getTestClient, getTestClientConf } from
|
|
2
|
-
import { PlClient } from
|
|
3
|
-
import { PlDriver, PlDriverDefinition } from
|
|
4
|
-
import { Dispatcher, request } from
|
|
5
|
-
import { GrpcClientProviderFactory } from
|
|
6
|
-
import { test, expect } from
|
|
1
|
+
import { getTestClient, getTestClientConf } from "../test/test_config";
|
|
2
|
+
import { PlClient } from "./client";
|
|
3
|
+
import { PlDriver, PlDriverDefinition } from "./driver";
|
|
4
|
+
import { Dispatcher, request } from "undici";
|
|
5
|
+
import { GrpcClientProviderFactory } from "./grpc";
|
|
6
|
+
import { test, expect } from "vitest";
|
|
7
7
|
|
|
8
|
-
test(
|
|
9
|
-
|
|
8
|
+
test("test client init", async () => {
|
|
9
|
+
await getTestClient(undefined);
|
|
10
10
|
});
|
|
11
11
|
|
|
12
|
-
test(
|
|
13
|
-
const aRootName =
|
|
12
|
+
test("test client alternative root init", async () => {
|
|
13
|
+
const aRootName = "test_root";
|
|
14
14
|
const { conf, auth } = await getTestClientConf();
|
|
15
|
-
|
|
15
|
+
await PlClient.init({ ...conf, alternativeRoot: aRootName }, auth);
|
|
16
16
|
const clientB = await PlClient.init(conf, auth);
|
|
17
17
|
const result = await clientB.deleteAlternativeRoot(aRootName);
|
|
18
18
|
expect(result).toBe(true);
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
test(
|
|
22
|
-
|
|
21
|
+
test("test client init 2", async () => {
|
|
22
|
+
await getTestClient();
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
interface SimpleDriver extends PlDriver {
|
|
@@ -27,22 +27,26 @@ interface SimpleDriver extends PlDriver {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
const SimpleDriverDefinition: PlDriverDefinition<SimpleDriver> = {
|
|
30
|
-
name:
|
|
31
|
-
init(
|
|
30
|
+
name: "SimpleDriver",
|
|
31
|
+
init(
|
|
32
|
+
pl: PlClient,
|
|
33
|
+
grpcClientProviderFactory: GrpcClientProviderFactory,
|
|
34
|
+
httpDispatcher: Dispatcher,
|
|
35
|
+
): SimpleDriver {
|
|
32
36
|
return {
|
|
33
37
|
async ping(): Promise<string> {
|
|
34
|
-
const response = await request(
|
|
35
|
-
dispatcher: httpDispatcher
|
|
38
|
+
const response = await request("https://cdn.milaboratory.com/ping", {
|
|
39
|
+
dispatcher: httpDispatcher,
|
|
36
40
|
});
|
|
37
41
|
return await response.body.text();
|
|
38
42
|
},
|
|
39
|
-
close() {}
|
|
43
|
+
close() {},
|
|
40
44
|
};
|
|
41
|
-
}
|
|
45
|
+
},
|
|
42
46
|
};
|
|
43
47
|
|
|
44
|
-
test(
|
|
48
|
+
test("test driver", async () => {
|
|
45
49
|
const client = await getTestClient();
|
|
46
50
|
const drv = client.getDriver(SimpleDriverDefinition);
|
|
47
|
-
expect(await drv.ping()).toEqual(
|
|
51
|
+
expect(await drv.ping()).toEqual("pong");
|
|
48
52
|
});
|
package/src/core/client.ts
CHANGED
|
@@ -1,28 +1,31 @@
|
|
|
1
|
-
import type { AuthOps, PlClientConfig, PlConnectionStatusListener, wireProtocol } from
|
|
2
|
-
import type { PlCallOps } from
|
|
3
|
-
import { LLPlClient } from
|
|
4
|
-
import type { AnyResourceRef } from
|
|
5
|
-
import { PlTransaction, toGlobalResourceId, TxCommitConflict } from
|
|
6
|
-
import { createHash } from
|
|
7
|
-
import type { OptionalResourceId, ResourceId } from
|
|
8
|
-
import { ensureResourceIdNotNull, isNullResourceId, NullResourceId } from
|
|
9
|
-
import { ClientRoot } from
|
|
10
|
-
import type { MiLogger, RetryOptions } from
|
|
11
|
-
import { assertNever, createRetryState, nextRetryStateOrError } from
|
|
12
|
-
import type { PlDriver, PlDriverDefinition } from
|
|
13
|
-
import type {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
import {
|
|
18
|
-
import
|
|
19
|
-
import type {
|
|
20
|
-
import {
|
|
21
|
-
import type {
|
|
22
|
-
import {
|
|
23
|
-
import
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
1
|
+
import type { AuthOps, PlClientConfig, PlConnectionStatusListener, wireProtocol } from "./config";
|
|
2
|
+
import type { PlCallOps } from "./ll_client";
|
|
3
|
+
import { LLPlClient } from "./ll_client";
|
|
4
|
+
import type { AnyResourceRef } from "./transaction";
|
|
5
|
+
import { PlTransaction, toGlobalResourceId, TxCommitConflict } from "./transaction";
|
|
6
|
+
import { createHash } from "node:crypto";
|
|
7
|
+
import type { OptionalResourceId, ResourceId } from "./types";
|
|
8
|
+
import { ensureResourceIdNotNull, isNullResourceId, NullResourceId } from "./types";
|
|
9
|
+
import { ClientRoot } from "../helpers/pl";
|
|
10
|
+
import type { MiLogger, RetryOptions } from "@milaboratories/ts-helpers";
|
|
11
|
+
import { assertNever, createRetryState, nextRetryStateOrError } from "@milaboratories/ts-helpers";
|
|
12
|
+
import type { PlDriver, PlDriverDefinition } from "./driver";
|
|
13
|
+
import type {
|
|
14
|
+
MaintenanceAPI_Ping_Response,
|
|
15
|
+
MaintenanceAPI_License_Response,
|
|
16
|
+
} from "../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api";
|
|
17
|
+
import { MaintenanceAPI_Ping_Response_Compression } from "../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api";
|
|
18
|
+
import * as tp from "node:timers/promises";
|
|
19
|
+
import type { Dispatcher } from "undici";
|
|
20
|
+
import { LRUCache } from "lru-cache";
|
|
21
|
+
import type { ResourceDataCacheRecord } from "./cache";
|
|
22
|
+
import type { FinalResourceDataPredicate } from "./final";
|
|
23
|
+
import { DefaultFinalResourceDataPredicate } from "./final";
|
|
24
|
+
import type { AllTxStat, TxStat } from "./stat";
|
|
25
|
+
import { addStat, initialTxStat } from "./stat";
|
|
26
|
+
import type { WireConnection } from "./wire";
|
|
27
|
+
import { advisoryLock } from "./advisory_locks";
|
|
28
|
+
import { plAddressToConfig } from "./config";
|
|
26
29
|
|
|
27
30
|
export type TxOps = PlCallOps & {
|
|
28
31
|
sync?: boolean;
|
|
@@ -35,7 +38,7 @@ const defaultTxOps = {
|
|
|
35
38
|
sync: false,
|
|
36
39
|
};
|
|
37
40
|
|
|
38
|
-
const AnonymousClientRoot =
|
|
41
|
+
const AnonymousClientRoot = "AnonymousRoot";
|
|
39
42
|
|
|
40
43
|
function alternativeRootFieldName(alternativeRoot: string): string {
|
|
41
44
|
return `alternative_root_${alternativeRoot}`;
|
|
@@ -55,12 +58,15 @@ export class PlClient {
|
|
|
55
58
|
/** Last resort measure to solve complicated race conditions in pl. */
|
|
56
59
|
private readonly defaultRetryOptions: RetryOptions;
|
|
57
60
|
|
|
58
|
-
private readonly buildLLPlClient: (
|
|
61
|
+
private readonly buildLLPlClient: (
|
|
62
|
+
shouldUseGzip: boolean,
|
|
63
|
+
wireProtocol?: wireProtocol,
|
|
64
|
+
) => Promise<LLPlClient>;
|
|
59
65
|
private _ll?: LLPlClient;
|
|
60
66
|
|
|
61
67
|
private get ll(): LLPlClient {
|
|
62
68
|
if (this._ll === undefined) {
|
|
63
|
-
throw new Error(
|
|
69
|
+
throw new Error("LLPlClient not initialized");
|
|
64
70
|
}
|
|
65
71
|
return this._ll;
|
|
66
72
|
}
|
|
@@ -93,9 +99,13 @@ export class PlClient {
|
|
|
93
99
|
logger?: MiLogger;
|
|
94
100
|
} = {},
|
|
95
101
|
) {
|
|
96
|
-
const conf =
|
|
102
|
+
const conf =
|
|
103
|
+
typeof configOrAddress === "string" ? plAddressToConfig(configOrAddress) : configOrAddress;
|
|
97
104
|
|
|
98
|
-
this.buildLLPlClient = async (
|
|
105
|
+
this.buildLLPlClient = async (
|
|
106
|
+
shouldUseGzip: boolean,
|
|
107
|
+
wireProtocol?: wireProtocol,
|
|
108
|
+
): Promise<LLPlClient> => {
|
|
99
109
|
if (wireProtocol) conf.wireProtocol = wireProtocol;
|
|
100
110
|
return await LLPlClient.build(conf, { auth, ...ops, shouldUseGzip });
|
|
101
111
|
};
|
|
@@ -108,18 +118,18 @@ export class PlClient {
|
|
|
108
118
|
sizeCalculation: (v) => (v.basicData.data?.length ?? 0) + 64,
|
|
109
119
|
});
|
|
110
120
|
switch (conf.retryBackoffAlgorithm) {
|
|
111
|
-
case
|
|
121
|
+
case "exponential":
|
|
112
122
|
this.defaultRetryOptions = {
|
|
113
|
-
type:
|
|
123
|
+
type: "exponentialBackoff",
|
|
114
124
|
initialDelay: conf.retryInitialDelay,
|
|
115
125
|
maxAttempts: conf.retryMaxAttempts,
|
|
116
126
|
backoffMultiplier: conf.retryExponentialBackoffMultiplier,
|
|
117
127
|
jitter: conf.retryJitter,
|
|
118
128
|
};
|
|
119
129
|
break;
|
|
120
|
-
case
|
|
130
|
+
case "linear":
|
|
121
131
|
this.defaultRetryOptions = {
|
|
122
|
-
type:
|
|
132
|
+
type: "linearBackoff",
|
|
123
133
|
initialDelay: conf.retryInitialDelay,
|
|
124
134
|
maxAttempts: conf.retryMaxAttempts,
|
|
125
135
|
backoffStep: conf.retryLinearBackoffStep,
|
|
@@ -180,7 +190,7 @@ export class PlClient {
|
|
|
180
190
|
}
|
|
181
191
|
|
|
182
192
|
private checkInitialized() {
|
|
183
|
-
if (!this.initialized) throw new Error(
|
|
193
|
+
if (!this.initialized) throw new Error("Client not initialized");
|
|
184
194
|
}
|
|
185
195
|
|
|
186
196
|
public get clientRoot(): ResourceId {
|
|
@@ -195,7 +205,7 @@ export class PlClient {
|
|
|
195
205
|
|
|
196
206
|
/** Currently implements custom logic to emulate future behaviour with single root. */
|
|
197
207
|
private async init() {
|
|
198
|
-
if (this.initialized) throw new Error(
|
|
208
|
+
if (this.initialized) throw new Error("Already initialized");
|
|
199
209
|
|
|
200
210
|
// Initial client is created without gzip to perform server ping and detect optimal wire protocol.
|
|
201
211
|
// LLPlClient.build() internally calls detectOptimalWireProtocol() which starts with default 'grpc',
|
|
@@ -208,8 +218,8 @@ export class PlClient {
|
|
|
208
218
|
|
|
209
219
|
// calculating reproducible root name from the username
|
|
210
220
|
const user = this._ll.authUser;
|
|
211
|
-
const mainRootName
|
|
212
|
-
|
|
221
|
+
const mainRootName =
|
|
222
|
+
user === null ? AnonymousClientRoot : createHash("sha256").update(user).digest("hex");
|
|
213
223
|
|
|
214
224
|
this._serverInfo = await this.ping();
|
|
215
225
|
if (this._serverInfo.compression === MaintenanceAPI_Ping_Response_Compression.GZIP) {
|
|
@@ -217,7 +227,7 @@ export class PlClient {
|
|
|
217
227
|
this._ll = await this.buildLLPlClient(true, wireProtocol);
|
|
218
228
|
}
|
|
219
229
|
|
|
220
|
-
this._clientRoot = await this._withTx(
|
|
230
|
+
this._clientRoot = await this._withTx("initialization", true, NullResourceId, async (tx) => {
|
|
221
231
|
let mainRoot: AnyResourceRef;
|
|
222
232
|
|
|
223
233
|
if (await tx.checkResourceNameExists(mainRootName))
|
|
@@ -238,7 +248,7 @@ export class PlClient {
|
|
|
238
248
|
|
|
239
249
|
const altRoot = tx.createEphemeral(ClientRoot);
|
|
240
250
|
tx.lock(altRoot);
|
|
241
|
-
tx.createField(aFId,
|
|
251
|
+
tx.createField(aFId, "Dynamic");
|
|
242
252
|
tx.setField(aFId, altRoot);
|
|
243
253
|
await tx.commit();
|
|
244
254
|
|
|
@@ -251,8 +261,8 @@ export class PlClient {
|
|
|
251
261
|
public async deleteAlternativeRoot(alternativeRootName: string): Promise<boolean> {
|
|
252
262
|
this.checkInitialized();
|
|
253
263
|
if (this.ll.conf.alternativeRoot !== undefined)
|
|
254
|
-
throw new Error(
|
|
255
|
-
return await this.withWriteTx(
|
|
264
|
+
throw new Error("Initialized with alternative root.");
|
|
265
|
+
return await this.withWriteTx("delete-alternative-root", async (tx) => {
|
|
256
266
|
const fId = {
|
|
257
267
|
resourceId: tx.clientRoot,
|
|
258
268
|
fieldName: alternativeRootFieldName(alternativeRootName),
|
|
@@ -307,7 +317,7 @@ export class PlClient {
|
|
|
307
317
|
// collecting stat
|
|
308
318
|
this._txConflictStat = addStat(this._txConflictStat, tx.stat);
|
|
309
319
|
} else {
|
|
310
|
-
|
|
320
|
+
// collecting stat
|
|
311
321
|
this._txErrorStat = addStat(this._txErrorStat, tx.stat);
|
|
312
322
|
throw e;
|
|
313
323
|
}
|
|
@@ -325,8 +335,7 @@ export class PlClient {
|
|
|
325
335
|
|
|
326
336
|
if (ok) {
|
|
327
337
|
// syncing on transaction if requested
|
|
328
|
-
if (ops?.sync === undefined ? this.forceSync : ops?.sync)
|
|
329
|
-
await this.ll.txSync(txId);
|
|
338
|
+
if (ops?.sync === undefined ? this.forceSync : ops?.sync) await this.ll.txSync(txId);
|
|
330
339
|
|
|
331
340
|
// introducing artificial delay, if requested
|
|
332
341
|
if (writable && this.txDelay > 0)
|
package/src/core/config.test.ts
CHANGED
|
@@ -1,86 +1,86 @@
|
|
|
1
|
-
import { DEFAULT_RO_TX_TIMEOUT, DEFAULT_RW_TX_TIMEOUT, plAddressToConfig } from
|
|
2
|
-
import { test, expect } from
|
|
1
|
+
import { DEFAULT_RO_TX_TIMEOUT, DEFAULT_RW_TX_TIMEOUT, plAddressToConfig } from "./config";
|
|
2
|
+
import { test, expect } from "vitest";
|
|
3
3
|
|
|
4
|
-
test(
|
|
5
|
-
const conf = plAddressToConfig(
|
|
4
|
+
test("config form url no auth", () => {
|
|
5
|
+
const conf = plAddressToConfig("http://127.0.0.1:6345");
|
|
6
6
|
expect(conf.user).toBeUndefined();
|
|
7
7
|
expect(conf.password).toBeUndefined();
|
|
8
8
|
});
|
|
9
9
|
|
|
10
|
-
test(
|
|
11
|
-
const conf = plAddressToConfig(
|
|
12
|
-
expect(conf.user).toEqual(
|
|
13
|
-
expect(conf.password).toEqual(
|
|
10
|
+
test("config form url with auth", () => {
|
|
11
|
+
const conf = plAddressToConfig("http://user1:password2@127.0.0.1:6345");
|
|
12
|
+
expect(conf.user).toEqual("user1");
|
|
13
|
+
expect(conf.password).toEqual("password2");
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
test(
|
|
17
|
-
const conf = plAddressToConfig(
|
|
18
|
-
expect(conf.user).toEqual(
|
|
19
|
-
expect(conf.password).toEqual(
|
|
16
|
+
test("config form url with auth and special symbols", () => {
|
|
17
|
+
const conf = plAddressToConfig("http://user1:password232$@127.0.0.1:6345");
|
|
18
|
+
expect(conf.user).toEqual("user1");
|
|
19
|
+
expect(conf.password).toEqual("password232$");
|
|
20
20
|
expect(conf.defaultROTransactionTimeout).toEqual(DEFAULT_RO_TX_TIMEOUT);
|
|
21
21
|
expect(conf.defaultRWTransactionTimeout).toEqual(DEFAULT_RW_TX_TIMEOUT);
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
test(
|
|
25
|
-
const conf = plAddressToConfig(
|
|
26
|
-
expect(conf.user).toEqual(
|
|
27
|
-
expect(conf.password).toEqual(
|
|
24
|
+
test("config form url with auth and special symbols and tx timeout", () => {
|
|
25
|
+
const conf = plAddressToConfig("http://user1:password232$@127.0.0.1:6345/?tx-timeout=11341");
|
|
26
|
+
expect(conf.user).toEqual("user1");
|
|
27
|
+
expect(conf.password).toEqual("password232$");
|
|
28
28
|
expect(conf.defaultROTransactionTimeout).toEqual(11341);
|
|
29
29
|
expect(conf.defaultRWTransactionTimeout).toEqual(11341);
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
test(
|
|
33
|
-
const conf = plAddressToConfig(
|
|
34
|
-
expect(conf.user).toEqual(
|
|
35
|
-
expect(conf.password).toEqual(
|
|
32
|
+
test("config form url with auth and special symbols and ro tx timeout", () => {
|
|
33
|
+
const conf = plAddressToConfig("http://user1:password232$@127.0.0.1:6345/?ro-tx-timeout=11341");
|
|
34
|
+
expect(conf.user).toEqual("user1");
|
|
35
|
+
expect(conf.password).toEqual("password232$");
|
|
36
36
|
expect(conf.defaultROTransactionTimeout).toEqual(11341);
|
|
37
37
|
expect(conf.defaultRWTransactionTimeout).toEqual(DEFAULT_RW_TX_TIMEOUT);
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
test(
|
|
41
|
-
const config = plAddressToConfig(
|
|
42
|
-
expect(config.hostAndPort).toBe(
|
|
40
|
+
test("should correctly handle http URL with no explicit port, defaulting to 80", () => {
|
|
41
|
+
const config = plAddressToConfig("http://example.com");
|
|
42
|
+
expect(config.hostAndPort).toBe("example.com:80");
|
|
43
43
|
expect(config.ssl).toBe(false);
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
test(
|
|
47
|
-
const config = plAddressToConfig(
|
|
48
|
-
expect(config.hostAndPort).toBe(
|
|
46
|
+
test("should correctly handle http URL with explicit port 80", () => {
|
|
47
|
+
const config = plAddressToConfig("http://example.com:80");
|
|
48
|
+
expect(config.hostAndPort).toBe("example.com:80");
|
|
49
49
|
expect(config.ssl).toBe(false);
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
-
test(
|
|
53
|
-
const config = plAddressToConfig(
|
|
54
|
-
expect(config.hostAndPort).toBe(
|
|
52
|
+
test("should correctly handle https URL with no explicit port, defaulting to 443", () => {
|
|
53
|
+
const config = plAddressToConfig("https://example.com");
|
|
54
|
+
expect(config.hostAndPort).toBe("example.com:443");
|
|
55
55
|
expect(config.ssl).toBe(true);
|
|
56
56
|
});
|
|
57
57
|
|
|
58
|
-
test(
|
|
59
|
-
const config = plAddressToConfig(
|
|
60
|
-
expect(config.hostAndPort).toBe(
|
|
58
|
+
test("should correctly handle https URL with explicit port 443", () => {
|
|
59
|
+
const config = plAddressToConfig("https://example.com:443");
|
|
60
|
+
expect(config.hostAndPort).toBe("example.com:443");
|
|
61
61
|
expect(config.ssl).toBe(true);
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
-
test(
|
|
65
|
-
const config = plAddressToConfig(
|
|
66
|
-
expect(config.hostAndPort).toBe(
|
|
64
|
+
test("should retain non-default port for http URL", () => {
|
|
65
|
+
const config = plAddressToConfig("http://example.com:8080");
|
|
66
|
+
expect(config.hostAndPort).toBe("example.com:8080");
|
|
67
67
|
expect(config.ssl).toBe(false);
|
|
68
68
|
});
|
|
69
69
|
|
|
70
|
-
test(
|
|
71
|
-
const config = plAddressToConfig(
|
|
72
|
-
expect(config.hostAndPort).toBe(
|
|
70
|
+
test("should retain non-default port for https URL", () => {
|
|
71
|
+
const config = plAddressToConfig("https://example.com:8443");
|
|
72
|
+
expect(config.hostAndPort).toBe("example.com:8443");
|
|
73
73
|
expect(config.ssl).toBe(true);
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
-
test(
|
|
77
|
-
expect(() => plAddressToConfig(
|
|
78
|
-
|
|
76
|
+
test("should throw an error for grpc URL without an explicit port", () => {
|
|
77
|
+
expect(() => plAddressToConfig("grpc://example.com")).toThrow(
|
|
78
|
+
"Port must be specified explicitly for grpc: protocol.",
|
|
79
79
|
);
|
|
80
80
|
});
|
|
81
81
|
|
|
82
|
-
test(
|
|
83
|
-
expect(() => plAddressToConfig(
|
|
84
|
-
|
|
82
|
+
test("should throw an error for tls URL without an explicit port", () => {
|
|
83
|
+
expect(() => plAddressToConfig("tls://example.com")).toThrow(
|
|
84
|
+
"Port must be specified explicitly for tls: protocol.",
|
|
85
85
|
);
|
|
86
86
|
});
|