@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
package/src/core/config.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { ProxySettings } from
|
|
2
|
-
import type { ExponentialBackoffRetryOptions } from
|
|
1
|
+
import type { ProxySettings } from "@milaboratories/pl-http";
|
|
2
|
+
import type { ExponentialBackoffRetryOptions } from "@milaboratories/ts-helpers";
|
|
3
3
|
|
|
4
|
-
export const SUPPORTED_WIRE_PROTOCOLS = [
|
|
4
|
+
export const SUPPORTED_WIRE_PROTOCOLS = ["grpc", "rest"] as const;
|
|
5
5
|
export type wireProtocol = (typeof SUPPORTED_WIRE_PROTOCOLS)[number];
|
|
6
6
|
|
|
7
7
|
/** Base configuration structure for PL client */
|
|
@@ -69,7 +69,7 @@ export interface PlClientConfig {
|
|
|
69
69
|
* What type of backoff strategy to use in transaction retries
|
|
70
70
|
* (pl uses optimistic transaction model with regular retries in write transactions)
|
|
71
71
|
*/
|
|
72
|
-
retryBackoffAlgorithm:
|
|
72
|
+
retryBackoffAlgorithm: "exponential" | "linear";
|
|
73
73
|
|
|
74
74
|
/** Maximal number of attempts in */
|
|
75
75
|
retryMaxAttempts: number;
|
|
@@ -95,7 +95,7 @@ export const DEFAULT_AUTH_MAX_REFRESH = 12 * 24 * 60 * 60;
|
|
|
95
95
|
|
|
96
96
|
export const DEFAULT_MAX_CACHE_BYTES = 128_000_000; // 128 Mb
|
|
97
97
|
|
|
98
|
-
export const DEFAULT_RETRY_BACKOFF_ALGORITHM =
|
|
98
|
+
export const DEFAULT_RETRY_BACKOFF_ALGORITHM = "exponential";
|
|
99
99
|
export const DEFAULT_RETRY_MAX_ATTEMPTS = 21; // 1st attempt + 20 retries
|
|
100
100
|
export const DEFAULT_RETRY_INITIAL_DELAY = 20; // 20 ms * <jitter> of sleep after first failure
|
|
101
101
|
export const DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER = 1.5; // + 50% on each round
|
|
@@ -103,7 +103,7 @@ export const DEFAULT_RETRY_LINEAR_BACKOFF_STEP = 50; // + 50 ms
|
|
|
103
103
|
export const DEFAULT_RETRY_JITTER = 0.3; // 30%
|
|
104
104
|
|
|
105
105
|
export const DefaultRetryOptions: ExponentialBackoffRetryOptions = {
|
|
106
|
-
type:
|
|
106
|
+
type: "exponentialBackoff",
|
|
107
107
|
maxAttempts: DEFAULT_RETRY_MAX_ATTEMPTS,
|
|
108
108
|
initialDelay: DEFAULT_RETRY_INITIAL_DELAY,
|
|
109
109
|
backoffMultiplier: DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER,
|
|
@@ -113,12 +113,12 @@ export const DefaultRetryOptions: ExponentialBackoffRetryOptions = {
|
|
|
113
113
|
type PlConfigOverrides = Partial<
|
|
114
114
|
Pick<
|
|
115
115
|
PlClientConfig,
|
|
116
|
-
|
|
|
117
|
-
|
|
|
118
|
-
|
|
|
119
|
-
|
|
|
120
|
-
|
|
|
121
|
-
|
|
|
116
|
+
| "ssl"
|
|
117
|
+
| "defaultRequestTimeout"
|
|
118
|
+
| "defaultROTransactionTimeout"
|
|
119
|
+
| "defaultRWTransactionTimeout"
|
|
120
|
+
| "httpProxy"
|
|
121
|
+
| "grpcProxy"
|
|
122
122
|
>
|
|
123
123
|
>;
|
|
124
124
|
|
|
@@ -135,7 +135,7 @@ export function plAddressToConfig(
|
|
|
135
135
|
address: string,
|
|
136
136
|
overrides: PlConfigOverrides = {},
|
|
137
137
|
): PlClientConfig {
|
|
138
|
-
if (address.indexOf(
|
|
138
|
+
if (address.indexOf("://") === -1)
|
|
139
139
|
// non-url address
|
|
140
140
|
return {
|
|
141
141
|
hostAndPort: address,
|
|
@@ -163,24 +163,24 @@ export function plAddressToConfig(
|
|
|
163
163
|
const url = new URL(address);
|
|
164
164
|
|
|
165
165
|
if (
|
|
166
|
-
url.protocol !==
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
166
|
+
url.protocol !== "https:" &&
|
|
167
|
+
url.protocol !== "http:" &&
|
|
168
|
+
url.protocol !== "grpc:" &&
|
|
169
|
+
url.protocol !== "tls:"
|
|
170
170
|
)
|
|
171
171
|
throw new Error(`Unexpected URL schema: ${url.protocol}`);
|
|
172
172
|
|
|
173
|
-
if (url.pathname !==
|
|
173
|
+
if (url.pathname !== "/" && url.pathname !== "")
|
|
174
174
|
throw new Error(`Unexpected URL path: ${url.pathname}`);
|
|
175
175
|
|
|
176
176
|
let port = url.port;
|
|
177
177
|
if (!port) {
|
|
178
178
|
switch (url.protocol) {
|
|
179
|
-
case
|
|
180
|
-
port =
|
|
179
|
+
case "http:":
|
|
180
|
+
port = "80";
|
|
181
181
|
break;
|
|
182
|
-
case
|
|
183
|
-
port =
|
|
182
|
+
case "https:":
|
|
183
|
+
port = "443";
|
|
184
184
|
break;
|
|
185
185
|
default:
|
|
186
186
|
throw new Error(`Port must be specified explicitly for ${url.protocol} protocol.`);
|
|
@@ -189,45 +189,45 @@ export function plAddressToConfig(
|
|
|
189
189
|
|
|
190
190
|
return {
|
|
191
191
|
hostAndPort: `${url.hostname}:${port}`,
|
|
192
|
-
alternativeRoot: url.searchParams.get(
|
|
193
|
-
ssl: url.protocol ===
|
|
192
|
+
alternativeRoot: url.searchParams.get("alternative-root") ?? undefined,
|
|
193
|
+
ssl: url.protocol === "https:" || url.protocol === "tls:",
|
|
194
194
|
|
|
195
|
-
wireProtocol: url.searchParams.get(
|
|
195
|
+
wireProtocol: (url.searchParams.get("wire-protocol") as wireProtocol) ?? undefined,
|
|
196
196
|
|
|
197
197
|
defaultRequestTimeout:
|
|
198
|
-
parseInt(url.searchParams.get(
|
|
198
|
+
parseInt(url.searchParams.get("request-timeout")) ?? DEFAULT_REQUEST_TIMEOUT,
|
|
199
199
|
defaultROTransactionTimeout:
|
|
200
|
-
parseInt(url.searchParams.get(
|
|
201
|
-
|
|
202
|
-
|
|
200
|
+
parseInt(url.searchParams.get("ro-tx-timeout")) ??
|
|
201
|
+
parseInt(url.searchParams.get("tx-timeout")) ??
|
|
202
|
+
DEFAULT_RO_TX_TIMEOUT,
|
|
203
203
|
defaultRWTransactionTimeout:
|
|
204
|
-
parseInt(url.searchParams.get(
|
|
205
|
-
|
|
206
|
-
|
|
204
|
+
parseInt(url.searchParams.get("rw-tx-timeout")) ??
|
|
205
|
+
parseInt(url.searchParams.get("tx-timeout")) ??
|
|
206
|
+
DEFAULT_RW_TX_TIMEOUT,
|
|
207
207
|
authTTLSeconds: DEFAULT_TOKEN_TTL_SECONDS,
|
|
208
208
|
authMaxRefreshSeconds: DEFAULT_AUTH_MAX_REFRESH,
|
|
209
|
-
grpcProxy: url.searchParams.get(
|
|
210
|
-
httpProxy: url.searchParams.get(
|
|
211
|
-
user: url.username ===
|
|
212
|
-
password: url.password ===
|
|
213
|
-
txDelay: parseInt(url.searchParams.get(
|
|
214
|
-
forceSync: Boolean(url.searchParams.get(
|
|
209
|
+
grpcProxy: url.searchParams.get("grpc-proxy") ?? undefined,
|
|
210
|
+
httpProxy: url.searchParams.get("http-proxy") ?? undefined,
|
|
211
|
+
user: url.username === "" ? undefined : url.username,
|
|
212
|
+
password: url.password === "" ? undefined : url.password,
|
|
213
|
+
txDelay: parseInt(url.searchParams.get("tx-delay")) ?? 0,
|
|
214
|
+
forceSync: Boolean(url.searchParams.get("force-sync")),
|
|
215
215
|
|
|
216
|
-
maxCacheBytes: parseInt(url.searchParams.get(
|
|
216
|
+
maxCacheBytes: parseInt(url.searchParams.get("max-cache-bytes")) ?? DEFAULT_MAX_CACHE_BYTES,
|
|
217
217
|
|
|
218
|
-
retryBackoffAlgorithm: (url.searchParams.get(
|
|
219
|
-
|
|
218
|
+
retryBackoffAlgorithm: (url.searchParams.get("retry-backoff-algorithm") ??
|
|
219
|
+
DEFAULT_RETRY_BACKOFF_ALGORITHM) as any,
|
|
220
220
|
retryMaxAttempts:
|
|
221
|
-
parseInt(url.searchParams.get(
|
|
221
|
+
parseInt(url.searchParams.get("retry-max-attempts")) ?? DEFAULT_RETRY_MAX_ATTEMPTS,
|
|
222
222
|
retryInitialDelay:
|
|
223
|
-
parseInt(url.searchParams.get(
|
|
223
|
+
parseInt(url.searchParams.get("retry-initial-delay")) ?? DEFAULT_RETRY_INITIAL_DELAY,
|
|
224
224
|
retryExponentialBackoffMultiplier:
|
|
225
|
-
parseInt(url.searchParams.get(
|
|
226
|
-
|
|
225
|
+
parseInt(url.searchParams.get("retry-exp-backoff-multiplier")) ??
|
|
226
|
+
DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER,
|
|
227
227
|
retryLinearBackoffStep:
|
|
228
|
-
parseInt(url.searchParams.get(
|
|
229
|
-
|
|
230
|
-
retryJitter: parseInt(url.searchParams.get(
|
|
228
|
+
parseInt(url.searchParams.get("retry-linear-backoff-step")) ??
|
|
229
|
+
DEFAULT_RETRY_LINEAR_BACKOFF_STEP,
|
|
230
|
+
retryJitter: parseInt(url.searchParams.get("retry-backoff-jitter")) ?? DEFAULT_RETRY_JITTER,
|
|
231
231
|
|
|
232
232
|
...overrides,
|
|
233
233
|
};
|
|
@@ -257,7 +257,7 @@ export interface AuthOps {
|
|
|
257
257
|
}
|
|
258
258
|
|
|
259
259
|
/** Connection status. */
|
|
260
|
-
export type PlConnectionStatus =
|
|
260
|
+
export type PlConnectionStatus = "OK" | "Disconnected" | "Unauthenticated";
|
|
261
261
|
|
|
262
262
|
/** Listener that will be called each time connection status changes. */
|
|
263
263
|
export type PlConnectionStatusListener = (status: PlConnectionStatus) => void;
|
|
@@ -1,70 +1,76 @@
|
|
|
1
|
-
import { withTempRoot } from
|
|
2
|
-
import { StructTestResource } from
|
|
3
|
-
import { toGlobalFieldId } from
|
|
4
|
-
import { test, expect } from
|
|
5
|
-
import { sleep } from
|
|
6
|
-
import { DisconnectedError } from
|
|
1
|
+
import { withTempRoot } from "../test/test_config";
|
|
2
|
+
import { StructTestResource } from "../helpers/pl";
|
|
3
|
+
import { toGlobalFieldId } from "./transaction";
|
|
4
|
+
import { test, expect } from "vitest";
|
|
5
|
+
import { sleep } from "@milaboratories/ts-helpers";
|
|
6
|
+
import { DisconnectedError } from "./errors";
|
|
7
7
|
|
|
8
|
-
test(
|
|
9
|
-
await withTempRoot(
|
|
10
|
-
|
|
11
|
-
await
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
tx.createField(f0, 'Dynamic');
|
|
18
|
-
tx.createField(f1, 'Dynamic');
|
|
19
|
-
tx.setField(f0, r0);
|
|
20
|
-
tx.setField(f1, r1);
|
|
21
|
-
|
|
22
|
-
await proxy?.disconnectAll();
|
|
8
|
+
test("connectivity: disconnect during tx", async () => {
|
|
9
|
+
await withTempRoot(
|
|
10
|
+
async (pl, proxy) => {
|
|
11
|
+
await expect(async () => {
|
|
12
|
+
await pl.withWriteTx("resource1", async (tx) => {
|
|
13
|
+
const r0 = tx.createStruct(StructTestResource);
|
|
14
|
+
const r1 = tx.createStruct(StructTestResource);
|
|
15
|
+
const f0 = { resourceId: tx.clientRoot, fieldName: "test0" };
|
|
16
|
+
const f1 = { resourceId: tx.clientRoot, fieldName: "test1" };
|
|
23
17
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
18
|
+
tx.createField(f0, "Dynamic");
|
|
19
|
+
tx.createField(f1, "Dynamic");
|
|
20
|
+
tx.setField(f0, r0);
|
|
21
|
+
tx.setField(f1, r1);
|
|
22
|
+
|
|
23
|
+
await proxy?.disconnectAll();
|
|
24
|
+
|
|
25
|
+
await sleep(1);
|
|
26
|
+
|
|
27
|
+
const theField1 = { resourceId: r1, fieldName: "theField" };
|
|
28
|
+
tx.createField(theField1, "Input");
|
|
29
|
+
tx.lock(r1);
|
|
30
|
+
tx.setField(theField1, tx.getFutureFieldValue(r0, "theField", "Input"));
|
|
31
|
+
|
|
32
|
+
await tx.commit();
|
|
33
|
+
|
|
34
|
+
return [await r0.globalId, await toGlobalFieldId(theField1)];
|
|
35
|
+
});
|
|
36
|
+
}).rejects.toThrow(DisconnectedError);
|
|
37
|
+
},
|
|
38
|
+
{ viaTcpProxy: true },
|
|
39
|
+
);
|
|
37
40
|
});
|
|
38
41
|
|
|
39
|
-
test.skip(
|
|
40
|
-
await withTempRoot(
|
|
41
|
-
proxy
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
42
|
+
test.skip("connectivity: latency", async () => {
|
|
43
|
+
await withTempRoot(
|
|
44
|
+
async (pl, proxy) => {
|
|
45
|
+
proxy?.setLatency(10_000);
|
|
46
|
+
await expect(async () => {
|
|
47
|
+
const result = await pl.withWriteTx("resource1", async (tx) => {
|
|
48
|
+
const r0 = tx.createStruct(StructTestResource);
|
|
49
|
+
const r1 = tx.createStruct(StructTestResource);
|
|
50
|
+
const f0 = { resourceId: tx.clientRoot, fieldName: "test0" };
|
|
51
|
+
const f1 = { resourceId: tx.clientRoot, fieldName: "test1" };
|
|
52
|
+
|
|
53
|
+
tx.createField(f0, "Dynamic");
|
|
54
|
+
tx.createField(f1, "Dynamic");
|
|
55
|
+
tx.setField(f0, r0);
|
|
56
|
+
tx.setField(f1, r1);
|
|
57
|
+
|
|
58
|
+
const theField1 = { resourceId: r1, fieldName: "theField" };
|
|
59
|
+
tx.createField(theField1, "Input");
|
|
60
|
+
tx.lock(r1);
|
|
61
|
+
tx.setField(theField1, tx.getFutureFieldValue(r0, "theField", "Input"));
|
|
62
|
+
|
|
63
|
+
await tx.commit().catch((err) => console.log("error committing tx", err));
|
|
64
|
+
|
|
65
|
+
return [await r0.globalId, await toGlobalFieldId(theField1)];
|
|
66
|
+
});
|
|
63
67
|
|
|
64
|
-
|
|
68
|
+
console.log("result", result);
|
|
65
69
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
return result;
|
|
71
|
+
}).rejects.toThrow(Error);
|
|
72
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
73
|
+
},
|
|
74
|
+
{ viaTcpProxy: true },
|
|
75
|
+
);
|
|
70
76
|
}, 60_000);
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import fs from
|
|
2
|
-
import type { AuthInformation, PlClientConfig } from
|
|
3
|
-
import { plAddressToConfig } from
|
|
4
|
-
import canonicalize from
|
|
5
|
-
import YAML from
|
|
6
|
-
import * as os from
|
|
7
|
-
import * as path from
|
|
8
|
-
import { notEmpty } from
|
|
9
|
-
import { UnauthenticatedPlClient } from
|
|
10
|
-
import { PlClient } from
|
|
11
|
-
import { createHash } from
|
|
12
|
-
import { inferAuthRefreshTime } from
|
|
13
|
-
|
|
14
|
-
const CONFIG_FILE_LOCAL_JSON =
|
|
15
|
-
const CONFIG_FILE_USER_JSON = path.join(os.homedir(),
|
|
16
|
-
const CONFIG_FILE_LOCAL_YAML =
|
|
17
|
-
const CONFIG_FILE_USER_YAML = path.join(os.homedir(),
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import type { AuthInformation, PlClientConfig } from "./config";
|
|
3
|
+
import { plAddressToConfig } from "./config";
|
|
4
|
+
import canonicalize from "canonicalize";
|
|
5
|
+
import YAML from "yaml";
|
|
6
|
+
import * as os from "node:os";
|
|
7
|
+
import * as path from "node:path";
|
|
8
|
+
import { notEmpty } from "@milaboratories/ts-helpers";
|
|
9
|
+
import { UnauthenticatedPlClient } from "./unauth_client";
|
|
10
|
+
import { PlClient } from "./client";
|
|
11
|
+
import { createHash } from "node:crypto";
|
|
12
|
+
import { inferAuthRefreshTime } from "./auth";
|
|
13
|
+
|
|
14
|
+
const CONFIG_FILE_LOCAL_JSON = "pl.json";
|
|
15
|
+
const CONFIG_FILE_USER_JSON = path.join(os.homedir(), ".pl.json");
|
|
16
|
+
const CONFIG_FILE_LOCAL_YAML = "pl.yaml";
|
|
17
|
+
const CONFIG_FILE_USER_YAML = path.join(os.homedir(), ".pl.yaml");
|
|
18
18
|
const CONF_FILE_SEQUENCE = [
|
|
19
19
|
CONFIG_FILE_LOCAL_JSON,
|
|
20
20
|
CONFIG_FILE_LOCAL_YAML,
|
|
@@ -22,30 +22,30 @@ const CONF_FILE_SEQUENCE = [
|
|
|
22
22
|
CONFIG_FILE_USER_YAML,
|
|
23
23
|
];
|
|
24
24
|
|
|
25
|
-
const AUTH_DATA_FILE =
|
|
25
|
+
const AUTH_DATA_FILE = ".pl_auth.json";
|
|
26
26
|
|
|
27
27
|
type FileConfigOverrideFields =
|
|
28
|
-
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
28
|
+
| "grpcProxy"
|
|
29
|
+
| "httpProxy"
|
|
30
|
+
| "user"
|
|
31
|
+
| "password"
|
|
32
|
+
| "alternativeRoot"
|
|
33
|
+
| "defaultROTransactionTimeout"
|
|
34
|
+
| "defaultRWTransactionTimeout"
|
|
35
|
+
| "defaultRequestTimeout"
|
|
36
|
+
| "authTTLSeconds"
|
|
37
|
+
| "authMaxRefreshSeconds";
|
|
38
38
|
const FILE_CONFIG_OVERRIDE_FIELDS: FileConfigOverrideFields[] = [
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
"grpcProxy",
|
|
40
|
+
"httpProxy",
|
|
41
|
+
"user",
|
|
42
|
+
"password",
|
|
43
|
+
"alternativeRoot",
|
|
44
|
+
"defaultROTransactionTimeout",
|
|
45
|
+
"defaultRWTransactionTimeout",
|
|
46
|
+
"defaultRequestTimeout",
|
|
47
|
+
"authTTLSeconds",
|
|
48
|
+
"authMaxRefreshSeconds",
|
|
49
49
|
];
|
|
50
50
|
|
|
51
51
|
type PlConfigFile = {
|
|
@@ -62,8 +62,8 @@ interface AuthCache {
|
|
|
62
62
|
export function tryGetFileConfig(): [PlConfigFile, string] | undefined {
|
|
63
63
|
for (const confPath of CONF_FILE_SEQUENCE)
|
|
64
64
|
if (fs.existsSync(confPath)) {
|
|
65
|
-
const fileContent = fs.readFileSync(confPath, { encoding:
|
|
66
|
-
if (confPath.endsWith(
|
|
65
|
+
const fileContent = fs.readFileSync(confPath, { encoding: "utf-8" });
|
|
66
|
+
if (confPath.endsWith("json")) return [JSON.parse(fileContent) as PlConfigFile, confPath];
|
|
67
67
|
else return [YAML.parse(fileContent) as PlConfigFile, confPath];
|
|
68
68
|
}
|
|
69
69
|
return undefined;
|
|
@@ -83,7 +83,7 @@ function saveAuthInfoCallback(
|
|
|
83
83
|
expiration: inferAuthRefreshTime(newAuthInfo, authMaxRefreshSeconds),
|
|
84
84
|
} as AuthCache),
|
|
85
85
|
),
|
|
86
|
-
|
|
86
|
+
"utf8",
|
|
87
87
|
);
|
|
88
88
|
};
|
|
89
89
|
}
|
|
@@ -110,21 +110,21 @@ export async function defaultPlClient(): Promise<PlClient> {
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
if (config === undefined)
|
|
113
|
-
throw new Error(
|
|
113
|
+
throw new Error("Can't find configuration to create default platform client.");
|
|
114
114
|
|
|
115
115
|
if (process.env.PL_USER !== undefined) config.user = process.env.PL_USER;
|
|
116
116
|
|
|
117
117
|
if (process.env.PL_PASSWORD !== undefined) config.user = process.env.PL_PASSWORD;
|
|
118
118
|
|
|
119
|
-
const confHash = createHash(
|
|
119
|
+
const confHash = createHash("sha256")
|
|
120
120
|
.update(Buffer.from(canonicalize(config)!))
|
|
121
|
-
.digest(
|
|
121
|
+
.digest("base64");
|
|
122
122
|
|
|
123
123
|
let authInformation: AuthInformation | undefined = undefined;
|
|
124
124
|
|
|
125
125
|
// try recover auth information from cache
|
|
126
126
|
if (fs.existsSync(AUTH_DATA_FILE)) {
|
|
127
|
-
const cache: AuthCache = JSON.parse(fs.readFileSync(AUTH_DATA_FILE, { encoding:
|
|
127
|
+
const cache: AuthCache = JSON.parse(fs.readFileSync(AUTH_DATA_FILE, { encoding: "utf-8" }));
|
|
128
128
|
if (cache.confHash === confHash && cache.expiration > Date.now())
|
|
129
129
|
authInformation = cache.authInformation;
|
|
130
130
|
}
|
|
@@ -151,7 +151,7 @@ export async function defaultPlClient(): Promise<PlClient> {
|
|
|
151
151
|
expiration: inferAuthRefreshTime(authInformation, config.authMaxRefreshSeconds),
|
|
152
152
|
} as AuthCache),
|
|
153
153
|
),
|
|
154
|
-
|
|
154
|
+
"utf8",
|
|
155
155
|
);
|
|
156
156
|
}
|
|
157
157
|
|
package/src/core/driver.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { PlClient } from
|
|
2
|
-
import type { RpcOptions } from
|
|
3
|
-
import type { Dispatcher } from
|
|
4
|
-
import type { ResourceType } from
|
|
5
|
-
import type { WireClientProviderFactory } from
|
|
1
|
+
import type { PlClient } from "./client";
|
|
2
|
+
import type { RpcOptions } from "@protobuf-ts/runtime-rpc";
|
|
3
|
+
import type { Dispatcher } from "undici";
|
|
4
|
+
import type { ResourceType } from "./types";
|
|
5
|
+
import type { WireClientProviderFactory } from "./wire";
|
|
6
6
|
|
|
7
7
|
/** Drivers must implement this interface */
|
|
8
8
|
export interface PlDriver {
|
|
@@ -24,7 +24,7 @@ export interface PlDriverDefinition<Drv extends PlDriver> {
|
|
|
24
24
|
export function addRTypeToMetadata(rType: ResourceType, options?: RpcOptions) {
|
|
25
25
|
options = options ?? {};
|
|
26
26
|
options.meta = options.meta ?? {};
|
|
27
|
-
options.meta[
|
|
27
|
+
options.meta["resourceType"] = `${rType.name}:${rType.version}`;
|
|
28
28
|
|
|
29
29
|
return options;
|
|
30
30
|
}
|
package/src/core/error.test.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import * as tp from
|
|
2
|
-
import { isTimeoutOrCancelError } from
|
|
3
|
-
import { test, expect } from
|
|
1
|
+
import * as tp from "node:timers/promises";
|
|
2
|
+
import { isTimeoutOrCancelError } from "./errors";
|
|
3
|
+
import { test, expect } from "vitest";
|
|
4
4
|
|
|
5
|
-
test(
|
|
5
|
+
test("timeout of sleep error type detection", async () => {
|
|
6
6
|
let noError = false;
|
|
7
7
|
try {
|
|
8
8
|
await tp.setTimeout(1000, undefined, { signal: AbortSignal.timeout(10) });
|
|
9
9
|
noError = true;
|
|
10
10
|
} catch (err: unknown) {
|
|
11
|
-
expect((err as any).code).toStrictEqual(
|
|
11
|
+
expect((err as any).code).toStrictEqual("ABORT_ERR");
|
|
12
12
|
expect(isTimeoutOrCancelError(err)).toEqual(true);
|
|
13
13
|
}
|
|
14
14
|
expect(noError).toBe(false);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { ResourceType } from
|
|
1
|
+
import type { ResourceType } from "./types";
|
|
2
2
|
|
|
3
3
|
export type ErrorResourceData = {
|
|
4
4
|
message: string;
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
export const ErrorResourceType: ResourceType = {
|
|
8
|
-
name:
|
|
9
|
-
version:
|
|
8
|
+
name: "json/resourceError",
|
|
9
|
+
version: "1",
|
|
10
10
|
};
|