@milaboratories/pl-client 2.11.12 → 2.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
- # Pl URL
1
+ # Developer Guide
2
2
 
3
- ```
3
+ ## Pl URL
4
+
5
+ ```txt
4
6
  http(s)://address:port/?...parameters...
5
7
  ```
6
8
 
@@ -14,19 +16,19 @@ Parameters:
14
16
 
15
17
  Example:
16
18
 
17
- ```
19
+ ```txt
18
20
  http(s)://address:port/alternative-root=tmproot&request-timeout=10000
19
21
  ```
20
22
 
21
- # How to pull and build proto files
23
+ ## How to pull and build proto files
22
24
 
23
25
  Dependencies:
24
26
 
25
27
  - `protoc`
26
- - `brew install protobuf`
28
+ - `brew install protobuf`
27
29
  - you don't need `protoc-gen-js`, just run `npm install`
28
30
  - `protodep`
29
- - `go install github.com/milaboratory/protodep@v0.1.7-milab`
31
+ - `go install github.com/milaboratory/protodep@v0.1.7-milab`
30
32
 
31
33
  check that you have `${HOME}/go/bin` in `PATH`
32
34
  - `rsync`
@@ -35,25 +37,27 @@ Dependencies:
35
37
  ./sync-proto.sh
36
38
  ```
37
39
 
38
- # Running tests
40
+ ## Running tests
39
41
 
40
42
  Unauthenticated
41
43
 
42
- ```
43
- PL_ADDRESS="http://127.0.0.1:6345" npm run test
44
+ ```bash
45
+ PL_ADDRESS="http://127.0.0.1:6345" pnpm run test
44
46
  ```
45
47
 
46
48
  Authenticated
47
49
 
48
- ```
49
- PL_ADDRESS="http://127.0.0.1:6345" PL_TEST_USER="test-user" PL_TEST_PASSWORD="test-password" npm run test
50
+ ```bash
51
+ PL_ADDRESS="http://127.0.0.1:6345" PL_TEST_USER="test-user" PL_TEST_PASSWORD="test-password" pnpm run test
50
52
  ```
51
53
 
52
54
  Authentication information (token) cached in git-ignored `.test_auth.json` file.
53
55
 
54
- # FAQ
56
+ ## FAQ
57
+
58
+ ### mapfile
59
+
60
+ Default bash version on MacOS is 3. mapfile apprears only from 4. To fix issue with `command not found: mapfile` you should install and redeclare bash:
55
61
 
56
- ## mapfile
57
- Default bash version on MacOS is 3. mapfile apprears only from 4. To fix issue with `command not found: mapfile` you should install and redeclare bash:
58
62
  1. install bash with brew, it will install version 5
59
- 2. ln -s $(brew --prefix)/bin/bash /usr/local/bin/bash
63
+ 2. `ln -s $(brew --prefix)/bin/bash /usr/local/bin/bash`
@@ -7,8 +7,8 @@ const DEFAULT_TOKEN_TTL_SECONDS = 31 * 24 * 60 * 60;
7
7
  const DEFAULT_AUTH_MAX_REFRESH = 12 * 24 * 60 * 60;
8
8
  const DEFAULT_MAX_CACHE_BYTES = 128_000_000; // 128 Mb
9
9
  const DEFAULT_RETRY_BACKOFF_ALGORITHM = 'exponential';
10
- const DEFAULT_RETRY_MAX_ATTEMPTS = 16; // 1st attempt + 15 retries
11
- const DEFAULT_RETRY_INITIAL_DELAY = 14; // 14 ms * <jitter> of sleep after first failure
10
+ const DEFAULT_RETRY_MAX_ATTEMPTS = 21; // 1st attempt + 20 retries
11
+ const DEFAULT_RETRY_INITIAL_DELAY = 20; // 20 ms * <jitter> of sleep after first failure
12
12
  const DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER = 1.5; // + 50% on each round
13
13
  const DEFAULT_RETRY_LINEAR_BACKOFF_STEP = 50; // + 50 ms
14
14
  const DEFAULT_RETRY_JITTER = 0.3; // 30%
@@ -1 +1 @@
1
- {"version":3,"file":"config.cjs","sources":["../../src/core/config.ts"],"sourcesContent":["import type { ExponentialBackoffRetryOptions } from '@milaboratories/ts-helpers';\n\n/** Base configuration structure for PL client */\nexport interface PlClientConfig {\n /** Port and host of remote pl server */\n hostAndPort: string;\n\n /** If set, client will expose a nested object under a field with name `alternative_root_${alternativeRoot}` as a\n * client root. */\n alternativeRoot?: string;\n\n /** If true, client will establish tls connection to the server, using default\n * CA of node instance. */\n // Not implementing custom ssl validation logic for now.\n // Implementing it in a correct way is really nontrivial thing,\n // real use-cases should be considered.\n ssl: boolean;\n\n /** Default timeout in milliseconds for unary calls, like ping and login. */\n defaultRequestTimeout: number;\n\n /** Default timeout in milliseconds for read-write transaction, should be\n * adjusted for long round-trip or low bandwidth connections. */\n defaultRWTransactionTimeout: number;\n /** Default timeout in milliseconds for read-only transaction, should be\n * adjusted for long round-trip or low bandwidth connections. */\n defaultROTransactionTimeout: number;\n\n /** Controls what TTL will be requested from the server, when new JWT token\n * is requested. */\n authTTLSeconds: number;\n /** If token is older than this time, it will be refreshed regardless of its\n * expiration time. */\n authMaxRefreshSeconds: number;\n\n /** Proxy server URL to use for pl connection. */\n grpcProxy?: string;\n /** Proxy server URL to use for http connections of pl drivers, like file\n * downloading. */\n httpProxy?: string;\n\n /** Username extracted from pl URL. Ignored by {@link PlClient}, picked up by {@link defaultPlClient}. */\n user?: string;\n /** Password extracted from pl URL. Ignored by {@link PlClient}, picked up by {@link defaultPlClient}. */\n password?: string;\n\n /** Artificial delay introduced after write transactions completion, to\n * somewhat throttle the load on pl. Delay introduced after sync, if requested. */\n txDelay: number;\n\n /** Last resort measure to solve complicated race conditions in pl. */\n forceSync: boolean;\n\n /** Maximal number of bytes of resource state to cache */\n maxCacheBytes: number;\n\n //\n // Retry\n //\n\n /**\n * What type of backoff strategy to use in transaction retries\n * (pl uses optimistic transaction model with regular retries in write transactions)\n * */\n retryBackoffAlgorithm: 'exponential' | 'linear';\n\n /** Maximal number of attempts in */\n retryMaxAttempts: number;\n\n /** Delay after first failed attempt, in ms. */\n retryInitialDelay: number;\n\n /** Each time delay will be multiplied by this number (1.5 means plus on 50% each attempt) */\n retryExponentialBackoffMultiplier: number;\n\n /** [used only for ] This value will be added to the delay from the previous step, in ms */\n retryLinearBackoffStep: number;\n\n /** Value from 0 to 1, determine level of randomness to introduce to the backoff delays sequence. (0 meaning no randomness) */\n retryJitter: number;\n}\n\nexport const DEFAULT_REQUEST_TIMEOUT = 5_000;\nexport const DEFAULT_RO_TX_TIMEOUT = 300_000;\nexport const DEFAULT_RW_TX_TIMEOUT = 60_000;\nexport const DEFAULT_TOKEN_TTL_SECONDS = 31 * 24 * 60 * 60;\nexport const DEFAULT_AUTH_MAX_REFRESH = 12 * 24 * 60 * 60;\n\nexport const DEFAULT_MAX_CACHE_BYTES = 128_000_000; // 128 Mb\n\nexport const DEFAULT_RETRY_BACKOFF_ALGORITHM = 'exponential';\nexport const DEFAULT_RETRY_MAX_ATTEMPTS = 16; // 1st attempt + 15 retries\nexport const DEFAULT_RETRY_INITIAL_DELAY = 14; // 14 ms * <jitter> of sleep after first failure\nexport const DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER = 1.5; // + 50% on each round\nexport const DEFAULT_RETRY_LINEAR_BACKOFF_STEP = 50; // + 50 ms\nexport const DEFAULT_RETRY_JITTER = 0.3; // 30%\n\nexport const DefaultRetryOptions: ExponentialBackoffRetryOptions = {\n type: 'exponentialBackoff',\n maxAttempts: DEFAULT_RETRY_MAX_ATTEMPTS,\n initialDelay: DEFAULT_RETRY_INITIAL_DELAY,\n backoffMultiplier: DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER,\n jitter: DEFAULT_RETRY_JITTER,\n};\n\ntype PlConfigOverrides = Partial<\n Pick<\n PlClientConfig,\n | 'ssl'\n | 'defaultRequestTimeout'\n | 'defaultROTransactionTimeout'\n | 'defaultRWTransactionTimeout'\n | 'httpProxy'\n | 'grpcProxy'\n >\n>;\n\nfunction parseInt(s: string | null | undefined): number | undefined {\n if (!s) return undefined;\n const num = Number(s);\n if (Number.isNaN(num)) throw new Error(`Can't parse number: ${s}`);\n return num;\n}\n\n/** Parses pl url and creates a config object that can be passed to\n * {@link PlClient} of {@link UnauthenticatedPlClient}. */\nexport function plAddressToConfig(\n address: string,\n overrides: PlConfigOverrides = {},\n): PlClientConfig {\n if (address.indexOf('://') === -1)\n // non-url address\n return {\n hostAndPort: address,\n ssl: false,\n defaultRequestTimeout: DEFAULT_REQUEST_TIMEOUT,\n defaultROTransactionTimeout: DEFAULT_RO_TX_TIMEOUT,\n defaultRWTransactionTimeout: DEFAULT_RW_TX_TIMEOUT,\n authTTLSeconds: DEFAULT_TOKEN_TTL_SECONDS,\n authMaxRefreshSeconds: DEFAULT_AUTH_MAX_REFRESH,\n txDelay: 0,\n forceSync: false,\n\n maxCacheBytes: DEFAULT_MAX_CACHE_BYTES,\n\n retryBackoffAlgorithm: DEFAULT_RETRY_BACKOFF_ALGORITHM,\n retryMaxAttempts: DEFAULT_RETRY_MAX_ATTEMPTS,\n retryInitialDelay: DEFAULT_RETRY_INITIAL_DELAY,\n retryExponentialBackoffMultiplier: DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER,\n retryLinearBackoffStep: DEFAULT_RETRY_LINEAR_BACKOFF_STEP,\n retryJitter: DEFAULT_RETRY_JITTER,\n\n ...overrides,\n };\n\n const url = new URL(address);\n\n if (\n url.protocol !== 'https:'\n && url.protocol !== 'http:'\n && url.protocol !== 'grpc:'\n && url.protocol !== 'tls:'\n )\n throw new Error(`Unexpected URL schema: ${url.protocol}`);\n\n if (url.pathname !== '/' && url.pathname !== '')\n throw new Error(`Unexpected URL path: ${url.pathname}`);\n\n return {\n hostAndPort: url.host, // this also includes port\n alternativeRoot: url.searchParams.get('alternative-root') ?? undefined,\n ssl: url.protocol === 'https:' || url.protocol === 'tls:',\n defaultRequestTimeout:\n parseInt(url.searchParams.get('request-timeout')) ?? DEFAULT_REQUEST_TIMEOUT,\n defaultROTransactionTimeout:\n parseInt(url.searchParams.get('ro-tx-timeout'))\n ?? parseInt(url.searchParams.get('tx-timeout'))\n ?? DEFAULT_RO_TX_TIMEOUT,\n defaultRWTransactionTimeout:\n parseInt(url.searchParams.get('rw-tx-timeout'))\n ?? parseInt(url.searchParams.get('tx-timeout'))\n ?? DEFAULT_RW_TX_TIMEOUT,\n authTTLSeconds: DEFAULT_TOKEN_TTL_SECONDS,\n authMaxRefreshSeconds: DEFAULT_AUTH_MAX_REFRESH,\n grpcProxy: url.searchParams.get('grpc-proxy') ?? undefined,\n httpProxy: url.searchParams.get('http-proxy') ?? undefined,\n user: url.username === '' ? undefined : url.username,\n password: url.password === '' ? undefined : url.password,\n txDelay: parseInt(url.searchParams.get('tx-delay')) ?? 0,\n forceSync: Boolean(url.searchParams.get('force-sync')),\n\n maxCacheBytes: parseInt(url.searchParams.get('max-cache-bytes')) ?? DEFAULT_MAX_CACHE_BYTES,\n\n retryBackoffAlgorithm: (url.searchParams.get('retry-backoff-algorithm')\n ?? DEFAULT_RETRY_BACKOFF_ALGORITHM) as any,\n retryMaxAttempts:\n parseInt(url.searchParams.get('retry-max-attempts')) ?? DEFAULT_RETRY_MAX_ATTEMPTS,\n retryInitialDelay:\n parseInt(url.searchParams.get('retry-initial-delay')) ?? DEFAULT_RETRY_INITIAL_DELAY,\n retryExponentialBackoffMultiplier:\n parseInt(url.searchParams.get('retry-exp-backoff-multiplier'))\n ?? DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER,\n retryLinearBackoffStep:\n parseInt(url.searchParams.get('retry-linear-backoff-step'))\n ?? DEFAULT_RETRY_LINEAR_BACKOFF_STEP,\n retryJitter: parseInt(url.searchParams.get('retry-backoff-jitter')) ?? DEFAULT_RETRY_JITTER,\n\n ...overrides,\n };\n}\n\n/**\n * Authorization data / JWT Token.\n * Absent JWT Token tells the client to connect as anonymous user.\n * */\nexport interface AuthInformation {\n /** Absent token means anonymous access */\n jwtToken?: string;\n}\n\nexport const AnonymousAuthInformation: AuthInformation = {};\n\n/** Authorization related settings to pass to {@link PlClient}. */\nexport interface AuthOps {\n /** Initial authorization information */\n authInformation: AuthInformation;\n /** Will be executed after successful authorization information refresh */\n readonly onUpdate?: (newInfo: AuthInformation) => void;\n /** Will be executed if auth-related error happens during normal client operation */\n readonly onAuthError?: () => void;\n /** Will be executed if error encountered during token update */\n readonly onUpdateError?: (error: unknown) => void;\n}\n\n/** Connection status. */\nexport type PlConnectionStatus = 'OK' | 'Disconnected' | 'Unauthenticated';\n\n/** Listener that will be called each time connection status changes. */\nexport type PlConnectionStatusListener = (status: PlConnectionStatus) => void;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.cjs","sources":["../../src/core/config.ts"],"sourcesContent":["import type { ExponentialBackoffRetryOptions } from '@milaboratories/ts-helpers';\n\n/** Base configuration structure for PL client */\nexport interface PlClientConfig {\n /** Port and host of remote pl server */\n hostAndPort: string;\n\n /** If set, client will expose a nested object under a field with name `alternative_root_${alternativeRoot}` as a\n * client root. */\n alternativeRoot?: string;\n\n /** If true, client will establish tls connection to the server, using default\n * CA of node instance. */\n // Not implementing custom ssl validation logic for now.\n // Implementing it in a correct way is really nontrivial thing,\n // real use-cases should be considered.\n ssl: boolean;\n\n /** Default timeout in milliseconds for unary calls, like ping and login. */\n defaultRequestTimeout: number;\n\n /** Default timeout in milliseconds for read-write transaction, should be\n * adjusted for long round-trip or low bandwidth connections. */\n defaultRWTransactionTimeout: number;\n /** Default timeout in milliseconds for read-only transaction, should be\n * adjusted for long round-trip or low bandwidth connections. */\n defaultROTransactionTimeout: number;\n\n /** Controls what TTL will be requested from the server, when new JWT token\n * is requested. */\n authTTLSeconds: number;\n /** If token is older than this time, it will be refreshed regardless of its\n * expiration time. */\n authMaxRefreshSeconds: number;\n\n /** Proxy server URL to use for pl connection. */\n grpcProxy?: string;\n /** Proxy server URL to use for http connections of pl drivers, like file\n * downloading. */\n httpProxy?: string;\n\n /** Username extracted from pl URL. Ignored by {@link PlClient}, picked up by {@link defaultPlClient}. */\n user?: string;\n /** Password extracted from pl URL. Ignored by {@link PlClient}, picked up by {@link defaultPlClient}. */\n password?: string;\n\n /** Artificial delay introduced after write transactions completion, to\n * somewhat throttle the load on pl. Delay introduced after sync, if requested. */\n txDelay: number;\n\n /** Last resort measure to solve complicated race conditions in pl. */\n forceSync: boolean;\n\n /** Maximal number of bytes of resource state to cache */\n maxCacheBytes: number;\n\n //\n // Retry\n //\n\n /**\n * What type of backoff strategy to use in transaction retries\n * (pl uses optimistic transaction model with regular retries in write transactions)\n * */\n retryBackoffAlgorithm: 'exponential' | 'linear';\n\n /** Maximal number of attempts in */\n retryMaxAttempts: number;\n\n /** Delay after first failed attempt, in ms. */\n retryInitialDelay: number;\n\n /** Each time delay will be multiplied by this number (1.5 means plus on 50% each attempt) */\n retryExponentialBackoffMultiplier: number;\n\n /** [used only for ] This value will be added to the delay from the previous step, in ms */\n retryLinearBackoffStep: number;\n\n /** Value from 0 to 1, determine level of randomness to introduce to the backoff delays sequence. (0 meaning no randomness) */\n retryJitter: number;\n}\n\nexport const DEFAULT_REQUEST_TIMEOUT = 5_000;\nexport const DEFAULT_RO_TX_TIMEOUT = 300_000;\nexport const DEFAULT_RW_TX_TIMEOUT = 60_000;\nexport const DEFAULT_TOKEN_TTL_SECONDS = 31 * 24 * 60 * 60;\nexport const DEFAULT_AUTH_MAX_REFRESH = 12 * 24 * 60 * 60;\n\nexport const DEFAULT_MAX_CACHE_BYTES = 128_000_000; // 128 Mb\n\nexport const DEFAULT_RETRY_BACKOFF_ALGORITHM = 'exponential';\nexport const DEFAULT_RETRY_MAX_ATTEMPTS = 21; // 1st attempt + 20 retries\nexport const DEFAULT_RETRY_INITIAL_DELAY = 20; // 20 ms * <jitter> of sleep after first failure\nexport const DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER = 1.5; // + 50% on each round\nexport const DEFAULT_RETRY_LINEAR_BACKOFF_STEP = 50; // + 50 ms\nexport const DEFAULT_RETRY_JITTER = 0.3; // 30%\n\nexport const DefaultRetryOptions: ExponentialBackoffRetryOptions = {\n type: 'exponentialBackoff',\n maxAttempts: DEFAULT_RETRY_MAX_ATTEMPTS,\n initialDelay: DEFAULT_RETRY_INITIAL_DELAY,\n backoffMultiplier: DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER,\n jitter: DEFAULT_RETRY_JITTER,\n};\n\ntype PlConfigOverrides = Partial<\n Pick<\n PlClientConfig,\n | 'ssl'\n | 'defaultRequestTimeout'\n | 'defaultROTransactionTimeout'\n | 'defaultRWTransactionTimeout'\n | 'httpProxy'\n | 'grpcProxy'\n >\n>;\n\nfunction parseInt(s: string | null | undefined): number | undefined {\n if (!s) return undefined;\n const num = Number(s);\n if (Number.isNaN(num)) throw new Error(`Can't parse number: ${s}`);\n return num;\n}\n\n/** Parses pl url and creates a config object that can be passed to\n * {@link PlClient} of {@link UnauthenticatedPlClient}. */\nexport function plAddressToConfig(\n address: string,\n overrides: PlConfigOverrides = {},\n): PlClientConfig {\n if (address.indexOf('://') === -1)\n // non-url address\n return {\n hostAndPort: address,\n ssl: false,\n defaultRequestTimeout: DEFAULT_REQUEST_TIMEOUT,\n defaultROTransactionTimeout: DEFAULT_RO_TX_TIMEOUT,\n defaultRWTransactionTimeout: DEFAULT_RW_TX_TIMEOUT,\n authTTLSeconds: DEFAULT_TOKEN_TTL_SECONDS,\n authMaxRefreshSeconds: DEFAULT_AUTH_MAX_REFRESH,\n txDelay: 0,\n forceSync: false,\n\n maxCacheBytes: DEFAULT_MAX_CACHE_BYTES,\n\n retryBackoffAlgorithm: DEFAULT_RETRY_BACKOFF_ALGORITHM,\n retryMaxAttempts: DEFAULT_RETRY_MAX_ATTEMPTS,\n retryInitialDelay: DEFAULT_RETRY_INITIAL_DELAY,\n retryExponentialBackoffMultiplier: DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER,\n retryLinearBackoffStep: DEFAULT_RETRY_LINEAR_BACKOFF_STEP,\n retryJitter: DEFAULT_RETRY_JITTER,\n\n ...overrides,\n };\n\n const url = new URL(address);\n\n if (\n url.protocol !== 'https:'\n && url.protocol !== 'http:'\n && url.protocol !== 'grpc:'\n && url.protocol !== 'tls:'\n )\n throw new Error(`Unexpected URL schema: ${url.protocol}`);\n\n if (url.pathname !== '/' && url.pathname !== '')\n throw new Error(`Unexpected URL path: ${url.pathname}`);\n\n return {\n hostAndPort: url.host, // this also includes port\n alternativeRoot: url.searchParams.get('alternative-root') ?? undefined,\n ssl: url.protocol === 'https:' || url.protocol === 'tls:',\n defaultRequestTimeout:\n parseInt(url.searchParams.get('request-timeout')) ?? DEFAULT_REQUEST_TIMEOUT,\n defaultROTransactionTimeout:\n parseInt(url.searchParams.get('ro-tx-timeout'))\n ?? parseInt(url.searchParams.get('tx-timeout'))\n ?? DEFAULT_RO_TX_TIMEOUT,\n defaultRWTransactionTimeout:\n parseInt(url.searchParams.get('rw-tx-timeout'))\n ?? parseInt(url.searchParams.get('tx-timeout'))\n ?? DEFAULT_RW_TX_TIMEOUT,\n authTTLSeconds: DEFAULT_TOKEN_TTL_SECONDS,\n authMaxRefreshSeconds: DEFAULT_AUTH_MAX_REFRESH,\n grpcProxy: url.searchParams.get('grpc-proxy') ?? undefined,\n httpProxy: url.searchParams.get('http-proxy') ?? undefined,\n user: url.username === '' ? undefined : url.username,\n password: url.password === '' ? undefined : url.password,\n txDelay: parseInt(url.searchParams.get('tx-delay')) ?? 0,\n forceSync: Boolean(url.searchParams.get('force-sync')),\n\n maxCacheBytes: parseInt(url.searchParams.get('max-cache-bytes')) ?? DEFAULT_MAX_CACHE_BYTES,\n\n retryBackoffAlgorithm: (url.searchParams.get('retry-backoff-algorithm')\n ?? DEFAULT_RETRY_BACKOFF_ALGORITHM) as any,\n retryMaxAttempts:\n parseInt(url.searchParams.get('retry-max-attempts')) ?? DEFAULT_RETRY_MAX_ATTEMPTS,\n retryInitialDelay:\n parseInt(url.searchParams.get('retry-initial-delay')) ?? DEFAULT_RETRY_INITIAL_DELAY,\n retryExponentialBackoffMultiplier:\n parseInt(url.searchParams.get('retry-exp-backoff-multiplier'))\n ?? DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER,\n retryLinearBackoffStep:\n parseInt(url.searchParams.get('retry-linear-backoff-step'))\n ?? DEFAULT_RETRY_LINEAR_BACKOFF_STEP,\n retryJitter: parseInt(url.searchParams.get('retry-backoff-jitter')) ?? DEFAULT_RETRY_JITTER,\n\n ...overrides,\n };\n}\n\n/**\n * Authorization data / JWT Token.\n * Absent JWT Token tells the client to connect as anonymous user.\n * */\nexport interface AuthInformation {\n /** Absent token means anonymous access */\n jwtToken?: string;\n}\n\nexport const AnonymousAuthInformation: AuthInformation = {};\n\n/** Authorization related settings to pass to {@link PlClient}. */\nexport interface AuthOps {\n /** Initial authorization information */\n authInformation: AuthInformation;\n /** Will be executed after successful authorization information refresh */\n readonly onUpdate?: (newInfo: AuthInformation) => void;\n /** Will be executed if auth-related error happens during normal client operation */\n readonly onAuthError?: () => void;\n /** Will be executed if error encountered during token update */\n readonly onUpdateError?: (error: unknown) => void;\n}\n\n/** Connection status. */\nexport type PlConnectionStatus = 'OK' | 'Disconnected' | 'Unauthenticated';\n\n/** Listener that will be called each time connection status changes. */\nexport type PlConnectionStatusListener = (status: PlConnectionStatus) => void;\n"],"names":[],"mappings":"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"}
@@ -62,8 +62,8 @@ export declare const DEFAULT_TOKEN_TTL_SECONDS: number;
62
62
  export declare const DEFAULT_AUTH_MAX_REFRESH: number;
63
63
  export declare const DEFAULT_MAX_CACHE_BYTES = 128000000;
64
64
  export declare const DEFAULT_RETRY_BACKOFF_ALGORITHM = "exponential";
65
- export declare const DEFAULT_RETRY_MAX_ATTEMPTS = 16;
66
- export declare const DEFAULT_RETRY_INITIAL_DELAY = 14;
65
+ export declare const DEFAULT_RETRY_MAX_ATTEMPTS = 21;
66
+ export declare const DEFAULT_RETRY_INITIAL_DELAY = 20;
67
67
  export declare const DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER = 1.5;
68
68
  export declare const DEFAULT_RETRY_LINEAR_BACKOFF_STEP = 50;
69
69
  export declare const DEFAULT_RETRY_JITTER = 0.3;
@@ -5,8 +5,8 @@ const DEFAULT_TOKEN_TTL_SECONDS = 31 * 24 * 60 * 60;
5
5
  const DEFAULT_AUTH_MAX_REFRESH = 12 * 24 * 60 * 60;
6
6
  const DEFAULT_MAX_CACHE_BYTES = 128_000_000; // 128 Mb
7
7
  const DEFAULT_RETRY_BACKOFF_ALGORITHM = 'exponential';
8
- const DEFAULT_RETRY_MAX_ATTEMPTS = 16; // 1st attempt + 15 retries
9
- const DEFAULT_RETRY_INITIAL_DELAY = 14; // 14 ms * <jitter> of sleep after first failure
8
+ const DEFAULT_RETRY_MAX_ATTEMPTS = 21; // 1st attempt + 20 retries
9
+ const DEFAULT_RETRY_INITIAL_DELAY = 20; // 20 ms * <jitter> of sleep after first failure
10
10
  const DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER = 1.5; // + 50% on each round
11
11
  const DEFAULT_RETRY_LINEAR_BACKOFF_STEP = 50; // + 50 ms
12
12
  const DEFAULT_RETRY_JITTER = 0.3; // 30%
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sources":["../../src/core/config.ts"],"sourcesContent":["import type { ExponentialBackoffRetryOptions } from '@milaboratories/ts-helpers';\n\n/** Base configuration structure for PL client */\nexport interface PlClientConfig {\n /** Port and host of remote pl server */\n hostAndPort: string;\n\n /** If set, client will expose a nested object under a field with name `alternative_root_${alternativeRoot}` as a\n * client root. */\n alternativeRoot?: string;\n\n /** If true, client will establish tls connection to the server, using default\n * CA of node instance. */\n // Not implementing custom ssl validation logic for now.\n // Implementing it in a correct way is really nontrivial thing,\n // real use-cases should be considered.\n ssl: boolean;\n\n /** Default timeout in milliseconds for unary calls, like ping and login. */\n defaultRequestTimeout: number;\n\n /** Default timeout in milliseconds for read-write transaction, should be\n * adjusted for long round-trip or low bandwidth connections. */\n defaultRWTransactionTimeout: number;\n /** Default timeout in milliseconds for read-only transaction, should be\n * adjusted for long round-trip or low bandwidth connections. */\n defaultROTransactionTimeout: number;\n\n /** Controls what TTL will be requested from the server, when new JWT token\n * is requested. */\n authTTLSeconds: number;\n /** If token is older than this time, it will be refreshed regardless of its\n * expiration time. */\n authMaxRefreshSeconds: number;\n\n /** Proxy server URL to use for pl connection. */\n grpcProxy?: string;\n /** Proxy server URL to use for http connections of pl drivers, like file\n * downloading. */\n httpProxy?: string;\n\n /** Username extracted from pl URL. Ignored by {@link PlClient}, picked up by {@link defaultPlClient}. */\n user?: string;\n /** Password extracted from pl URL. Ignored by {@link PlClient}, picked up by {@link defaultPlClient}. */\n password?: string;\n\n /** Artificial delay introduced after write transactions completion, to\n * somewhat throttle the load on pl. Delay introduced after sync, if requested. */\n txDelay: number;\n\n /** Last resort measure to solve complicated race conditions in pl. */\n forceSync: boolean;\n\n /** Maximal number of bytes of resource state to cache */\n maxCacheBytes: number;\n\n //\n // Retry\n //\n\n /**\n * What type of backoff strategy to use in transaction retries\n * (pl uses optimistic transaction model with regular retries in write transactions)\n * */\n retryBackoffAlgorithm: 'exponential' | 'linear';\n\n /** Maximal number of attempts in */\n retryMaxAttempts: number;\n\n /** Delay after first failed attempt, in ms. */\n retryInitialDelay: number;\n\n /** Each time delay will be multiplied by this number (1.5 means plus on 50% each attempt) */\n retryExponentialBackoffMultiplier: number;\n\n /** [used only for ] This value will be added to the delay from the previous step, in ms */\n retryLinearBackoffStep: number;\n\n /** Value from 0 to 1, determine level of randomness to introduce to the backoff delays sequence. (0 meaning no randomness) */\n retryJitter: number;\n}\n\nexport const DEFAULT_REQUEST_TIMEOUT = 5_000;\nexport const DEFAULT_RO_TX_TIMEOUT = 300_000;\nexport const DEFAULT_RW_TX_TIMEOUT = 60_000;\nexport const DEFAULT_TOKEN_TTL_SECONDS = 31 * 24 * 60 * 60;\nexport const DEFAULT_AUTH_MAX_REFRESH = 12 * 24 * 60 * 60;\n\nexport const DEFAULT_MAX_CACHE_BYTES = 128_000_000; // 128 Mb\n\nexport const DEFAULT_RETRY_BACKOFF_ALGORITHM = 'exponential';\nexport const DEFAULT_RETRY_MAX_ATTEMPTS = 16; // 1st attempt + 15 retries\nexport const DEFAULT_RETRY_INITIAL_DELAY = 14; // 14 ms * <jitter> of sleep after first failure\nexport const DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER = 1.5; // + 50% on each round\nexport const DEFAULT_RETRY_LINEAR_BACKOFF_STEP = 50; // + 50 ms\nexport const DEFAULT_RETRY_JITTER = 0.3; // 30%\n\nexport const DefaultRetryOptions: ExponentialBackoffRetryOptions = {\n type: 'exponentialBackoff',\n maxAttempts: DEFAULT_RETRY_MAX_ATTEMPTS,\n initialDelay: DEFAULT_RETRY_INITIAL_DELAY,\n backoffMultiplier: DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER,\n jitter: DEFAULT_RETRY_JITTER,\n};\n\ntype PlConfigOverrides = Partial<\n Pick<\n PlClientConfig,\n | 'ssl'\n | 'defaultRequestTimeout'\n | 'defaultROTransactionTimeout'\n | 'defaultRWTransactionTimeout'\n | 'httpProxy'\n | 'grpcProxy'\n >\n>;\n\nfunction parseInt(s: string | null | undefined): number | undefined {\n if (!s) return undefined;\n const num = Number(s);\n if (Number.isNaN(num)) throw new Error(`Can't parse number: ${s}`);\n return num;\n}\n\n/** Parses pl url and creates a config object that can be passed to\n * {@link PlClient} of {@link UnauthenticatedPlClient}. */\nexport function plAddressToConfig(\n address: string,\n overrides: PlConfigOverrides = {},\n): PlClientConfig {\n if (address.indexOf('://') === -1)\n // non-url address\n return {\n hostAndPort: address,\n ssl: false,\n defaultRequestTimeout: DEFAULT_REQUEST_TIMEOUT,\n defaultROTransactionTimeout: DEFAULT_RO_TX_TIMEOUT,\n defaultRWTransactionTimeout: DEFAULT_RW_TX_TIMEOUT,\n authTTLSeconds: DEFAULT_TOKEN_TTL_SECONDS,\n authMaxRefreshSeconds: DEFAULT_AUTH_MAX_REFRESH,\n txDelay: 0,\n forceSync: false,\n\n maxCacheBytes: DEFAULT_MAX_CACHE_BYTES,\n\n retryBackoffAlgorithm: DEFAULT_RETRY_BACKOFF_ALGORITHM,\n retryMaxAttempts: DEFAULT_RETRY_MAX_ATTEMPTS,\n retryInitialDelay: DEFAULT_RETRY_INITIAL_DELAY,\n retryExponentialBackoffMultiplier: DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER,\n retryLinearBackoffStep: DEFAULT_RETRY_LINEAR_BACKOFF_STEP,\n retryJitter: DEFAULT_RETRY_JITTER,\n\n ...overrides,\n };\n\n const url = new URL(address);\n\n if (\n url.protocol !== 'https:'\n && url.protocol !== 'http:'\n && url.protocol !== 'grpc:'\n && url.protocol !== 'tls:'\n )\n throw new Error(`Unexpected URL schema: ${url.protocol}`);\n\n if (url.pathname !== '/' && url.pathname !== '')\n throw new Error(`Unexpected URL path: ${url.pathname}`);\n\n return {\n hostAndPort: url.host, // this also includes port\n alternativeRoot: url.searchParams.get('alternative-root') ?? undefined,\n ssl: url.protocol === 'https:' || url.protocol === 'tls:',\n defaultRequestTimeout:\n parseInt(url.searchParams.get('request-timeout')) ?? DEFAULT_REQUEST_TIMEOUT,\n defaultROTransactionTimeout:\n parseInt(url.searchParams.get('ro-tx-timeout'))\n ?? parseInt(url.searchParams.get('tx-timeout'))\n ?? DEFAULT_RO_TX_TIMEOUT,\n defaultRWTransactionTimeout:\n parseInt(url.searchParams.get('rw-tx-timeout'))\n ?? parseInt(url.searchParams.get('tx-timeout'))\n ?? DEFAULT_RW_TX_TIMEOUT,\n authTTLSeconds: DEFAULT_TOKEN_TTL_SECONDS,\n authMaxRefreshSeconds: DEFAULT_AUTH_MAX_REFRESH,\n grpcProxy: url.searchParams.get('grpc-proxy') ?? undefined,\n httpProxy: url.searchParams.get('http-proxy') ?? undefined,\n user: url.username === '' ? undefined : url.username,\n password: url.password === '' ? undefined : url.password,\n txDelay: parseInt(url.searchParams.get('tx-delay')) ?? 0,\n forceSync: Boolean(url.searchParams.get('force-sync')),\n\n maxCacheBytes: parseInt(url.searchParams.get('max-cache-bytes')) ?? DEFAULT_MAX_CACHE_BYTES,\n\n retryBackoffAlgorithm: (url.searchParams.get('retry-backoff-algorithm')\n ?? DEFAULT_RETRY_BACKOFF_ALGORITHM) as any,\n retryMaxAttempts:\n parseInt(url.searchParams.get('retry-max-attempts')) ?? DEFAULT_RETRY_MAX_ATTEMPTS,\n retryInitialDelay:\n parseInt(url.searchParams.get('retry-initial-delay')) ?? DEFAULT_RETRY_INITIAL_DELAY,\n retryExponentialBackoffMultiplier:\n parseInt(url.searchParams.get('retry-exp-backoff-multiplier'))\n ?? DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER,\n retryLinearBackoffStep:\n parseInt(url.searchParams.get('retry-linear-backoff-step'))\n ?? DEFAULT_RETRY_LINEAR_BACKOFF_STEP,\n retryJitter: parseInt(url.searchParams.get('retry-backoff-jitter')) ?? DEFAULT_RETRY_JITTER,\n\n ...overrides,\n };\n}\n\n/**\n * Authorization data / JWT Token.\n * Absent JWT Token tells the client to connect as anonymous user.\n * */\nexport interface AuthInformation {\n /** Absent token means anonymous access */\n jwtToken?: string;\n}\n\nexport const AnonymousAuthInformation: AuthInformation = {};\n\n/** Authorization related settings to pass to {@link PlClient}. */\nexport interface AuthOps {\n /** Initial authorization information */\n authInformation: AuthInformation;\n /** Will be executed after successful authorization information refresh */\n readonly onUpdate?: (newInfo: AuthInformation) => void;\n /** Will be executed if auth-related error happens during normal client operation */\n readonly onAuthError?: () => void;\n /** Will be executed if error encountered during token update */\n readonly onUpdateError?: (error: unknown) => void;\n}\n\n/** Connection status. */\nexport type PlConnectionStatus = 'OK' | 'Disconnected' | 'Unauthenticated';\n\n/** Listener that will be called each time connection status changes. */\nexport type PlConnectionStatusListener = (status: PlConnectionStatus) => void;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sources":["../../src/core/config.ts"],"sourcesContent":["import type { ExponentialBackoffRetryOptions } from '@milaboratories/ts-helpers';\n\n/** Base configuration structure for PL client */\nexport interface PlClientConfig {\n /** Port and host of remote pl server */\n hostAndPort: string;\n\n /** If set, client will expose a nested object under a field with name `alternative_root_${alternativeRoot}` as a\n * client root. */\n alternativeRoot?: string;\n\n /** If true, client will establish tls connection to the server, using default\n * CA of node instance. */\n // Not implementing custom ssl validation logic for now.\n // Implementing it in a correct way is really nontrivial thing,\n // real use-cases should be considered.\n ssl: boolean;\n\n /** Default timeout in milliseconds for unary calls, like ping and login. */\n defaultRequestTimeout: number;\n\n /** Default timeout in milliseconds for read-write transaction, should be\n * adjusted for long round-trip or low bandwidth connections. */\n defaultRWTransactionTimeout: number;\n /** Default timeout in milliseconds for read-only transaction, should be\n * adjusted for long round-trip or low bandwidth connections. */\n defaultROTransactionTimeout: number;\n\n /** Controls what TTL will be requested from the server, when new JWT token\n * is requested. */\n authTTLSeconds: number;\n /** If token is older than this time, it will be refreshed regardless of its\n * expiration time. */\n authMaxRefreshSeconds: number;\n\n /** Proxy server URL to use for pl connection. */\n grpcProxy?: string;\n /** Proxy server URL to use for http connections of pl drivers, like file\n * downloading. */\n httpProxy?: string;\n\n /** Username extracted from pl URL. Ignored by {@link PlClient}, picked up by {@link defaultPlClient}. */\n user?: string;\n /** Password extracted from pl URL. Ignored by {@link PlClient}, picked up by {@link defaultPlClient}. */\n password?: string;\n\n /** Artificial delay introduced after write transactions completion, to\n * somewhat throttle the load on pl. Delay introduced after sync, if requested. */\n txDelay: number;\n\n /** Last resort measure to solve complicated race conditions in pl. */\n forceSync: boolean;\n\n /** Maximal number of bytes of resource state to cache */\n maxCacheBytes: number;\n\n //\n // Retry\n //\n\n /**\n * What type of backoff strategy to use in transaction retries\n * (pl uses optimistic transaction model with regular retries in write transactions)\n * */\n retryBackoffAlgorithm: 'exponential' | 'linear';\n\n /** Maximal number of attempts in */\n retryMaxAttempts: number;\n\n /** Delay after first failed attempt, in ms. */\n retryInitialDelay: number;\n\n /** Each time delay will be multiplied by this number (1.5 means plus on 50% each attempt) */\n retryExponentialBackoffMultiplier: number;\n\n /** [used only for ] This value will be added to the delay from the previous step, in ms */\n retryLinearBackoffStep: number;\n\n /** Value from 0 to 1, determine level of randomness to introduce to the backoff delays sequence. (0 meaning no randomness) */\n retryJitter: number;\n}\n\nexport const DEFAULT_REQUEST_TIMEOUT = 5_000;\nexport const DEFAULT_RO_TX_TIMEOUT = 300_000;\nexport const DEFAULT_RW_TX_TIMEOUT = 60_000;\nexport const DEFAULT_TOKEN_TTL_SECONDS = 31 * 24 * 60 * 60;\nexport const DEFAULT_AUTH_MAX_REFRESH = 12 * 24 * 60 * 60;\n\nexport const DEFAULT_MAX_CACHE_BYTES = 128_000_000; // 128 Mb\n\nexport const DEFAULT_RETRY_BACKOFF_ALGORITHM = 'exponential';\nexport const DEFAULT_RETRY_MAX_ATTEMPTS = 21; // 1st attempt + 20 retries\nexport const DEFAULT_RETRY_INITIAL_DELAY = 20; // 20 ms * <jitter> of sleep after first failure\nexport const DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER = 1.5; // + 50% on each round\nexport const DEFAULT_RETRY_LINEAR_BACKOFF_STEP = 50; // + 50 ms\nexport const DEFAULT_RETRY_JITTER = 0.3; // 30%\n\nexport const DefaultRetryOptions: ExponentialBackoffRetryOptions = {\n type: 'exponentialBackoff',\n maxAttempts: DEFAULT_RETRY_MAX_ATTEMPTS,\n initialDelay: DEFAULT_RETRY_INITIAL_DELAY,\n backoffMultiplier: DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER,\n jitter: DEFAULT_RETRY_JITTER,\n};\n\ntype PlConfigOverrides = Partial<\n Pick<\n PlClientConfig,\n | 'ssl'\n | 'defaultRequestTimeout'\n | 'defaultROTransactionTimeout'\n | 'defaultRWTransactionTimeout'\n | 'httpProxy'\n | 'grpcProxy'\n >\n>;\n\nfunction parseInt(s: string | null | undefined): number | undefined {\n if (!s) return undefined;\n const num = Number(s);\n if (Number.isNaN(num)) throw new Error(`Can't parse number: ${s}`);\n return num;\n}\n\n/** Parses pl url and creates a config object that can be passed to\n * {@link PlClient} of {@link UnauthenticatedPlClient}. */\nexport function plAddressToConfig(\n address: string,\n overrides: PlConfigOverrides = {},\n): PlClientConfig {\n if (address.indexOf('://') === -1)\n // non-url address\n return {\n hostAndPort: address,\n ssl: false,\n defaultRequestTimeout: DEFAULT_REQUEST_TIMEOUT,\n defaultROTransactionTimeout: DEFAULT_RO_TX_TIMEOUT,\n defaultRWTransactionTimeout: DEFAULT_RW_TX_TIMEOUT,\n authTTLSeconds: DEFAULT_TOKEN_TTL_SECONDS,\n authMaxRefreshSeconds: DEFAULT_AUTH_MAX_REFRESH,\n txDelay: 0,\n forceSync: false,\n\n maxCacheBytes: DEFAULT_MAX_CACHE_BYTES,\n\n retryBackoffAlgorithm: DEFAULT_RETRY_BACKOFF_ALGORITHM,\n retryMaxAttempts: DEFAULT_RETRY_MAX_ATTEMPTS,\n retryInitialDelay: DEFAULT_RETRY_INITIAL_DELAY,\n retryExponentialBackoffMultiplier: DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER,\n retryLinearBackoffStep: DEFAULT_RETRY_LINEAR_BACKOFF_STEP,\n retryJitter: DEFAULT_RETRY_JITTER,\n\n ...overrides,\n };\n\n const url = new URL(address);\n\n if (\n url.protocol !== 'https:'\n && url.protocol !== 'http:'\n && url.protocol !== 'grpc:'\n && url.protocol !== 'tls:'\n )\n throw new Error(`Unexpected URL schema: ${url.protocol}`);\n\n if (url.pathname !== '/' && url.pathname !== '')\n throw new Error(`Unexpected URL path: ${url.pathname}`);\n\n return {\n hostAndPort: url.host, // this also includes port\n alternativeRoot: url.searchParams.get('alternative-root') ?? undefined,\n ssl: url.protocol === 'https:' || url.protocol === 'tls:',\n defaultRequestTimeout:\n parseInt(url.searchParams.get('request-timeout')) ?? DEFAULT_REQUEST_TIMEOUT,\n defaultROTransactionTimeout:\n parseInt(url.searchParams.get('ro-tx-timeout'))\n ?? parseInt(url.searchParams.get('tx-timeout'))\n ?? DEFAULT_RO_TX_TIMEOUT,\n defaultRWTransactionTimeout:\n parseInt(url.searchParams.get('rw-tx-timeout'))\n ?? parseInt(url.searchParams.get('tx-timeout'))\n ?? DEFAULT_RW_TX_TIMEOUT,\n authTTLSeconds: DEFAULT_TOKEN_TTL_SECONDS,\n authMaxRefreshSeconds: DEFAULT_AUTH_MAX_REFRESH,\n grpcProxy: url.searchParams.get('grpc-proxy') ?? undefined,\n httpProxy: url.searchParams.get('http-proxy') ?? undefined,\n user: url.username === '' ? undefined : url.username,\n password: url.password === '' ? undefined : url.password,\n txDelay: parseInt(url.searchParams.get('tx-delay')) ?? 0,\n forceSync: Boolean(url.searchParams.get('force-sync')),\n\n maxCacheBytes: parseInt(url.searchParams.get('max-cache-bytes')) ?? DEFAULT_MAX_CACHE_BYTES,\n\n retryBackoffAlgorithm: (url.searchParams.get('retry-backoff-algorithm')\n ?? DEFAULT_RETRY_BACKOFF_ALGORITHM) as any,\n retryMaxAttempts:\n parseInt(url.searchParams.get('retry-max-attempts')) ?? DEFAULT_RETRY_MAX_ATTEMPTS,\n retryInitialDelay:\n parseInt(url.searchParams.get('retry-initial-delay')) ?? DEFAULT_RETRY_INITIAL_DELAY,\n retryExponentialBackoffMultiplier:\n parseInt(url.searchParams.get('retry-exp-backoff-multiplier'))\n ?? DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER,\n retryLinearBackoffStep:\n parseInt(url.searchParams.get('retry-linear-backoff-step'))\n ?? DEFAULT_RETRY_LINEAR_BACKOFF_STEP,\n retryJitter: parseInt(url.searchParams.get('retry-backoff-jitter')) ?? DEFAULT_RETRY_JITTER,\n\n ...overrides,\n };\n}\n\n/**\n * Authorization data / JWT Token.\n * Absent JWT Token tells the client to connect as anonymous user.\n * */\nexport interface AuthInformation {\n /** Absent token means anonymous access */\n jwtToken?: string;\n}\n\nexport const AnonymousAuthInformation: AuthInformation = {};\n\n/** Authorization related settings to pass to {@link PlClient}. */\nexport interface AuthOps {\n /** Initial authorization information */\n authInformation: AuthInformation;\n /** Will be executed after successful authorization information refresh */\n readonly onUpdate?: (newInfo: AuthInformation) => void;\n /** Will be executed if auth-related error happens during normal client operation */\n readonly onAuthError?: () => void;\n /** Will be executed if error encountered during token update */\n readonly onUpdateError?: (error: unknown) => void;\n}\n\n/** Connection status. */\nexport type PlConnectionStatus = 'OK' | 'Disconnected' | 'Unauthenticated';\n\n/** Listener that will be called each time connection status changes. */\nexport type PlConnectionStatusListener = (status: PlConnectionStatus) => void;\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milaboratories/pl-client",
3
- "version": "2.11.12",
3
+ "version": "2.12.0",
4
4
  "engines": {
5
5
  "node": ">=20.3.0"
6
6
  },
@@ -33,8 +33,8 @@
33
33
  "undici": "~7.13.0",
34
34
  "utility-types": "^3.11.0",
35
35
  "yaml": "^2.8.0",
36
- "@milaboratories/ts-helpers": "1.4.6",
37
- "@milaboratories/pl-http": "1.1.7"
36
+ "@milaboratories/pl-http": "1.1.7",
37
+ "@milaboratories/ts-helpers": "1.4.7"
38
38
  },
39
39
  "devDependencies": {
40
40
  "typescript": "~5.6.3",
@@ -45,9 +45,9 @@
45
45
  "jest": "^29.7.0",
46
46
  "@jest/globals": "^29.7.0",
47
47
  "ts-jest": "^29.2.6",
48
+ "@milaboratories/ts-builder": "1.0.5",
48
49
  "@milaboratories/ts-configs": "1.0.6",
49
- "@milaboratories/build-configs": "1.0.8",
50
- "@milaboratories/ts-builder": "1.0.5"
50
+ "@milaboratories/build-configs": "1.0.8"
51
51
  },
52
52
  "scripts": {
53
53
  "type-check": "ts-builder types --target node",
@@ -89,8 +89,8 @@ export const DEFAULT_AUTH_MAX_REFRESH = 12 * 24 * 60 * 60;
89
89
  export const DEFAULT_MAX_CACHE_BYTES = 128_000_000; // 128 Mb
90
90
 
91
91
  export const DEFAULT_RETRY_BACKOFF_ALGORITHM = 'exponential';
92
- export const DEFAULT_RETRY_MAX_ATTEMPTS = 16; // 1st attempt + 15 retries
93
- export const DEFAULT_RETRY_INITIAL_DELAY = 14; // 14 ms * <jitter> of sleep after first failure
92
+ export const DEFAULT_RETRY_MAX_ATTEMPTS = 21; // 1st attempt + 20 retries
93
+ export const DEFAULT_RETRY_INITIAL_DELAY = 20; // 20 ms * <jitter> of sleep after first failure
94
94
  export const DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER = 1.5; // + 50% on each round
95
95
  export const DEFAULT_RETRY_LINEAR_BACKOFF_STEP = 50; // + 50 ms
96
96
  export const DEFAULT_RETRY_JITTER = 0.3; // 30%