@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.
Files changed (212) hide show
  1. package/README.md +2 -1
  2. package/dist/core/PromiseTracker.cjs +1 -3
  3. package/dist/core/PromiseTracker.cjs.map +1 -1
  4. package/dist/core/PromiseTracker.d.ts.map +1 -1
  5. package/dist/core/PromiseTracker.js +1 -3
  6. package/dist/core/PromiseTracker.js.map +1 -1
  7. package/dist/core/StatefulPromise.cjs +4 -4
  8. package/dist/core/StatefulPromise.cjs.map +1 -1
  9. package/dist/core/StatefulPromise.d.ts +1 -1
  10. package/dist/core/StatefulPromise.d.ts.map +1 -1
  11. package/dist/core/StatefulPromise.js +4 -4
  12. package/dist/core/StatefulPromise.js.map +1 -1
  13. package/dist/core/advisory_locks.cjs +1 -1
  14. package/dist/core/advisory_locks.cjs.map +1 -1
  15. package/dist/core/advisory_locks.js +1 -1
  16. package/dist/core/advisory_locks.js.map +1 -1
  17. package/dist/core/auth.cjs.map +1 -1
  18. package/dist/core/auth.d.ts +1 -1
  19. package/dist/core/auth.js.map +1 -1
  20. package/dist/core/cache.d.ts +1 -1
  21. package/dist/core/client.cjs +14 -14
  22. package/dist/core/client.cjs.map +1 -1
  23. package/dist/core/client.d.ts +11 -11
  24. package/dist/core/client.d.ts.map +1 -1
  25. package/dist/core/client.js +14 -14
  26. package/dist/core/client.js.map +1 -1
  27. package/dist/core/config.cjs +39 -39
  28. package/dist/core/config.cjs.map +1 -1
  29. package/dist/core/config.d.ts +5 -5
  30. package/dist/core/config.js +39 -39
  31. package/dist/core/config.js.map +1 -1
  32. package/dist/core/default_client.cjs +23 -23
  33. package/dist/core/default_client.cjs.map +1 -1
  34. package/dist/core/default_client.d.ts +3 -3
  35. package/dist/core/default_client.js +23 -23
  36. package/dist/core/default_client.js.map +1 -1
  37. package/dist/core/driver.cjs +1 -1
  38. package/dist/core/driver.cjs.map +1 -1
  39. package/dist/core/driver.d.ts +5 -5
  40. package/dist/core/driver.js +1 -1
  41. package/dist/core/driver.js.map +1 -1
  42. package/dist/core/error_resource.cjs +2 -2
  43. package/dist/core/error_resource.cjs.map +1 -1
  44. package/dist/core/error_resource.d.ts +1 -1
  45. package/dist/core/error_resource.js +2 -2
  46. package/dist/core/error_resource.js.map +1 -1
  47. package/dist/core/errors.cjs +24 -24
  48. package/dist/core/errors.cjs.map +1 -1
  49. package/dist/core/errors.d.ts +1 -1
  50. package/dist/core/errors.d.ts.map +1 -1
  51. package/dist/core/errors.js +24 -24
  52. package/dist/core/errors.js.map +1 -1
  53. package/dist/core/final.cjs +43 -43
  54. package/dist/core/final.cjs.map +1 -1
  55. package/dist/core/final.d.ts +3 -3
  56. package/dist/core/final.d.ts.map +1 -1
  57. package/dist/core/final.js +43 -43
  58. package/dist/core/final.js.map +1 -1
  59. package/dist/core/ll_client.cjs +50 -43
  60. package/dist/core/ll_client.cjs.map +1 -1
  61. package/dist/core/ll_client.d.ts +9 -9
  62. package/dist/core/ll_client.d.ts.map +1 -1
  63. package/dist/core/ll_client.js +50 -43
  64. package/dist/core/ll_client.js.map +1 -1
  65. package/dist/core/ll_transaction.cjs +9 -9
  66. package/dist/core/ll_transaction.cjs.map +1 -1
  67. package/dist/core/ll_transaction.d.ts +7 -7
  68. package/dist/core/ll_transaction.d.ts.map +1 -1
  69. package/dist/core/ll_transaction.js +9 -9
  70. package/dist/core/ll_transaction.js.map +1 -1
  71. package/dist/core/stat.cjs.map +1 -1
  72. package/dist/core/stat.d.ts +1 -1
  73. package/dist/core/stat.js.map +1 -1
  74. package/dist/core/transaction.cjs +46 -46
  75. package/dist/core/transaction.cjs.map +1 -1
  76. package/dist/core/transaction.d.ts +7 -7
  77. package/dist/core/transaction.d.ts.map +1 -1
  78. package/dist/core/transaction.js +46 -46
  79. package/dist/core/transaction.js.map +1 -1
  80. package/dist/core/type_conversion.cjs +22 -22
  81. package/dist/core/type_conversion.cjs.map +1 -1
  82. package/dist/core/type_conversion.d.ts +3 -3
  83. package/dist/core/type_conversion.d.ts.map +1 -1
  84. package/dist/core/type_conversion.js +22 -22
  85. package/dist/core/type_conversion.js.map +1 -1
  86. package/dist/core/types.cjs +25 -25
  87. package/dist/core/types.cjs.map +1 -1
  88. package/dist/core/types.d.ts +7 -7
  89. package/dist/core/types.js +25 -25
  90. package/dist/core/types.js.map +1 -1
  91. package/dist/core/unauth_client.cjs +6 -4
  92. package/dist/core/unauth_client.cjs.map +1 -1
  93. package/dist/core/unauth_client.d.ts +4 -4
  94. package/dist/core/unauth_client.d.ts.map +1 -1
  95. package/dist/core/unauth_client.js +6 -4
  96. package/dist/core/unauth_client.js.map +1 -1
  97. package/dist/core/websocket_stream.cjs +22 -20
  98. package/dist/core/websocket_stream.cjs.map +1 -1
  99. package/dist/core/websocket_stream.d.ts +3 -3
  100. package/dist/core/websocket_stream.d.ts.map +1 -1
  101. package/dist/core/websocket_stream.js +22 -20
  102. package/dist/core/websocket_stream.js.map +1 -1
  103. package/dist/core/wire.d.ts +6 -6
  104. package/dist/core/wire.d.ts.map +1 -1
  105. package/dist/helpers/pl.cjs +19 -19
  106. package/dist/helpers/pl.cjs.map +1 -1
  107. package/dist/helpers/pl.d.ts +2 -2
  108. package/dist/helpers/pl.js +19 -19
  109. package/dist/helpers/pl.js.map +1 -1
  110. package/dist/helpers/poll.cjs +6 -6
  111. package/dist/helpers/poll.cjs.map +1 -1
  112. package/dist/helpers/poll.d.ts +4 -4
  113. package/dist/helpers/poll.d.ts.map +1 -1
  114. package/dist/helpers/poll.js +6 -6
  115. package/dist/helpers/poll.js.map +1 -1
  116. package/dist/helpers/retry_strategy.cjs +1 -1
  117. package/dist/helpers/retry_strategy.cjs.map +1 -1
  118. package/dist/helpers/retry_strategy.d.ts.map +1 -1
  119. package/dist/helpers/retry_strategy.js +1 -1
  120. package/dist/helpers/retry_strategy.js.map +1 -1
  121. package/dist/helpers/state_helpers.d.ts +2 -2
  122. package/dist/helpers/tx_helpers.cjs +2 -2
  123. package/dist/helpers/tx_helpers.cjs.map +1 -1
  124. package/dist/helpers/tx_helpers.d.ts +2 -2
  125. package/dist/helpers/tx_helpers.d.ts.map +1 -1
  126. package/dist/helpers/tx_helpers.js +2 -2
  127. package/dist/helpers/tx_helpers.js.map +1 -1
  128. package/dist/index.d.ts +16 -16
  129. package/dist/proto-grpc/google/protobuf/struct.d.ts +1 -1
  130. package/dist/proto-grpc/google/protobuf/struct.d.ts.map +1 -1
  131. package/dist/proto-rest/index.cjs +4 -5
  132. package/dist/proto-rest/index.cjs.map +1 -1
  133. package/dist/proto-rest/index.d.ts +4 -4
  134. package/dist/proto-rest/index.d.ts.map +1 -1
  135. package/dist/proto-rest/index.js +4 -5
  136. package/dist/proto-rest/index.js.map +1 -1
  137. package/dist/proto-rest/plapi.d.ts.map +1 -1
  138. package/dist/test/tcp-proxy.cjs +11 -10
  139. package/dist/test/tcp-proxy.cjs.map +1 -1
  140. package/dist/test/tcp-proxy.d.ts +1 -1
  141. package/dist/test/tcp-proxy.d.ts.map +1 -1
  142. package/dist/test/tcp-proxy.js +11 -10
  143. package/dist/test/tcp-proxy.js.map +1 -1
  144. package/dist/test/test_config.cjs +21 -17
  145. package/dist/test/test_config.cjs.map +1 -1
  146. package/dist/test/test_config.d.ts +6 -6
  147. package/dist/test/test_config.d.ts.map +1 -1
  148. package/dist/test/test_config.js +21 -17
  149. package/dist/test/test_config.js.map +1 -1
  150. package/dist/util/pl.cjs +1 -1
  151. package/dist/util/pl.cjs.map +1 -1
  152. package/dist/util/pl.js +1 -1
  153. package/dist/util/pl.js.map +1 -1
  154. package/dist/util/util.cjs +1 -1
  155. package/dist/util/util.cjs.map +1 -1
  156. package/dist/util/util.js +1 -1
  157. package/dist/util/util.js.map +1 -1
  158. package/package.json +23 -23
  159. package/src/core/PromiseTracker.ts +3 -4
  160. package/src/core/StatefulPromise.ts +17 -8
  161. package/src/core/abstract_stream.ts +3 -4
  162. package/src/core/advisory_locks.ts +1 -1
  163. package/src/core/auth.ts +2 -2
  164. package/src/core/cache.ts +1 -1
  165. package/src/core/client.test.ts +25 -21
  166. package/src/core/client.ts +54 -45
  167. package/src/core/config.test.ts +44 -44
  168. package/src/core/config.ts +49 -49
  169. package/src/core/connectivity.test.ts +69 -63
  170. package/src/core/default_client.ts +46 -46
  171. package/src/core/driver.ts +6 -6
  172. package/src/core/error.test.ts +5 -5
  173. package/src/core/error_resource.ts +3 -3
  174. package/src/core/errors.ts +39 -31
  175. package/src/core/final.ts +48 -55
  176. package/src/core/ll_client.test.ts +53 -36
  177. package/src/core/ll_client.ts +125 -81
  178. package/src/core/ll_transaction.test.ts +75 -49
  179. package/src/core/ll_transaction.ts +37 -35
  180. package/src/core/stat.ts +1 -1
  181. package/src/core/transaction.test.ts +65 -65
  182. package/src/core/transaction.ts +91 -84
  183. package/src/core/type_conversion.ts +30 -31
  184. package/src/core/types.test.ts +6 -6
  185. package/src/core/types.ts +35 -35
  186. package/src/core/unauth_client.test.ts +18 -14
  187. package/src/core/unauth_client.ts +14 -12
  188. package/src/core/websocket_stream.test.ts +52 -52
  189. package/src/core/websocket_stream.ts +41 -37
  190. package/src/core/wire.ts +10 -8
  191. package/src/helpers/pl.ts +22 -22
  192. package/src/helpers/poll.ts +13 -27
  193. package/src/helpers/retry_strategy.ts +2 -4
  194. package/src/helpers/rich_resource_types.test.ts +2 -2
  195. package/src/helpers/state_helpers.ts +3 -3
  196. package/src/helpers/tx_helpers.ts +9 -7
  197. package/src/index.ts +16 -16
  198. package/src/proto-grpc/google/protobuf/struct.ts +1 -1
  199. package/src/proto-rest/index.ts +17 -18
  200. package/src/proto-rest/plapi.ts +1472 -1472
  201. package/src/test/tcp-proxy.ts +55 -54
  202. package/src/test/test_config.test.ts +3 -3
  203. package/src/test/test_config.ts +51 -46
  204. package/src/util/pl.ts +1 -1
  205. package/src/util/util.test.ts +5 -5
  206. package/src/util/util.ts +1 -1
  207. package/dist/helpers/rich_resource_types.d.ts +0 -2
  208. package/dist/helpers/rich_resource_types.d.ts.map +0 -1
  209. package/dist/helpers/smart_accessors.d.ts +0 -2
  210. package/dist/helpers/smart_accessors.d.ts.map +0 -1
  211. package/src/helpers/rich_resource_types.ts +0 -84
  212. package/src/helpers/smart_accessors.ts +0 -146
@@ -1,11 +1,11 @@
1
- import { expect, test } from 'vitest';
1
+ import { expect, test } from "vitest";
2
2
  import {
3
3
  createGlobalResourceId,
4
4
  createLocalResourceId,
5
5
  NullResourceId,
6
6
  resourceIdFromString,
7
- resourceIdToString
8
- } from './types';
7
+ resourceIdToString,
8
+ } from "./types";
9
9
 
10
10
  test.each(
11
11
  [
@@ -13,11 +13,11 @@ test.each(
13
13
  createGlobalResourceId(true, 0x3457748574857n),
14
14
  createGlobalResourceId(false, 0x3457748574857n),
15
15
  createLocalResourceId(true, 1234, 34423),
16
- createLocalResourceId(false, 1234, 34423)
16
+ createLocalResourceId(false, 1234, 34423),
17
17
  ].map((rid) => ({
18
18
  name: resourceIdToString(rid),
19
- rid
20
- }))
19
+ rid,
20
+ })),
21
21
  )(`resource id to and from string: $name`, ({ rid }) => {
22
22
  expect(resourceIdFromString(resourceIdToString(rid))).toEqual(rid);
23
23
  });
package/src/core/types.ts CHANGED
@@ -1,17 +1,17 @@
1
- import { cachedDeserialize, notEmpty } from '@milaboratories/ts-helpers';
1
+ import { cachedDeserialize, notEmpty } from "@milaboratories/ts-helpers";
2
2
 
3
3
  // more details here: https://egghead.io/blog/using-branded-types-in-typescript
4
4
  declare const __resource_id_type__: unique symbol;
5
5
  type BrandResourceId<B> = bigint & { [__resource_id_type__]: B };
6
6
 
7
7
  /** Global resource id */
8
- export type ResourceId = BrandResourceId<'global'>;
8
+ export type ResourceId = BrandResourceId<"global">;
9
9
 
10
10
  /** Null resource id */
11
- export type NullResourceId = BrandResourceId<'null'>;
11
+ export type NullResourceId = BrandResourceId<"null">;
12
12
 
13
13
  /** Local resource id */
14
- export type LocalResourceId = BrandResourceId<'local'>;
14
+ export type LocalResourceId = BrandResourceId<"local">;
15
15
 
16
16
  /** Any non-null resource id */
17
17
  export type AnyResourceId = ResourceId | LocalResourceId;
@@ -33,7 +33,7 @@ export function isNotNullResourceId(resourceId: OptionalResourceId): resourceId
33
33
  }
34
34
 
35
35
  export function ensureResourceIdNotNull(resourceId: OptionalResourceId): ResourceId {
36
- if (!isNotNullResourceId(resourceId)) throw new Error('null resource id');
36
+ if (!isNotNullResourceId(resourceId)) throw new Error("null resource id");
37
37
  return resourceId;
38
38
  }
39
39
 
@@ -43,13 +43,13 @@ export function isAnyResourceId(resourceId: bigint): resourceId is AnyResourceId
43
43
 
44
44
  // see local / global resource logic below...
45
45
 
46
- export type ResourceKind = 'Structural' | 'Value';
46
+ export type ResourceKind = "Structural" | "Value";
47
47
 
48
- export type FieldType = 'Input' | 'Output' | 'Service' | 'OTW' | 'Dynamic' | 'MTW';
48
+ export type FieldType = "Input" | "Output" | "Service" | "OTW" | "Dynamic" | "MTW";
49
49
 
50
- export type FutureFieldType = 'Output' | 'Input' | 'Service';
50
+ export type FutureFieldType = "Output" | "Input" | "Service";
51
51
 
52
- export type FieldStatus = 'Empty' | 'Assigned' | 'Resolved';
52
+ export type FieldStatus = "Empty" | "Assigned" | "Resolved";
53
53
 
54
54
  export interface ResourceType {
55
55
  readonly name: string;
@@ -174,16 +174,16 @@ export function createLocalResourceId(
174
174
  localTxId: number,
175
175
  ): LocalResourceId {
176
176
  if (
177
- localCounterValue > MaxLocalId
178
- || localTxId > MaxTxId
179
- || localCounterValue < 0
180
- || localTxId <= 0
177
+ localCounterValue > MaxLocalId ||
178
+ localTxId > MaxTxId ||
179
+ localCounterValue < 0 ||
180
+ localTxId <= 0
181
181
  )
182
- throw Error('wrong local id or tx id');
183
- return ((isRoot ? ResourceIdRootMask : 0n)
184
- | ResourceIdLocalMask
185
- | BigInt(localCounterValue)
186
- | (BigInt(localTxId) << LocalResourceIdTxIdOffset)) as LocalResourceId;
182
+ throw Error("wrong local id or tx id");
183
+ return ((isRoot ? ResourceIdRootMask : 0n) |
184
+ ResourceIdLocalMask |
185
+ BigInt(localCounterValue) |
186
+ (BigInt(localTxId) << LocalResourceIdTxIdOffset)) as LocalResourceId;
187
187
  }
188
188
 
189
189
  export function createGlobalResourceId(isRoot: boolean, unmaskedId: bigint): ResourceId {
@@ -198,40 +198,40 @@ export function checkLocalityOfResourceId(resourceId: AnyResourceId, expectedTxI
198
198
  if (!isLocalResourceId(resourceId)) return;
199
199
  if (extractTxId(resourceId) !== expectedTxId)
200
200
  throw Error(
201
- 'local id from another transaction, globalize id before leaking it from the transaction',
201
+ "local id from another transaction, globalize id before leaking it from the transaction",
202
202
  );
203
203
  }
204
204
 
205
205
  export function resourceIdToString(resourceId: OptionalAnyResourceId): string {
206
- if (isNullResourceId(resourceId)) return 'XX:0x0';
206
+ if (isNullResourceId(resourceId)) return "XX:0x0";
207
207
  if (isLocalResourceId(resourceId))
208
208
  return (
209
- (isRootResourceId(resourceId) ? 'R' : 'N')
210
- + 'L:0x'
211
- + (LocalIdMask & resourceId).toString(16)
212
- + '[0x'
213
- + extractTxId(resourceId).toString(16)
214
- + ']'
209
+ (isRootResourceId(resourceId) ? "R" : "N") +
210
+ "L:0x" +
211
+ (LocalIdMask & resourceId).toString(16) +
212
+ "[0x" +
213
+ extractTxId(resourceId).toString(16) +
214
+ "]"
215
215
  );
216
216
  else
217
217
  return (
218
- (isRootResourceId(resourceId) ? 'R' : 'N')
219
- + 'G:0x'
220
- + (NoFlagsIdMask & resourceId).toString(16)
218
+ (isRootResourceId(resourceId) ? "R" : "N") +
219
+ "G:0x" +
220
+ (NoFlagsIdMask & resourceId).toString(16)
221
221
  );
222
222
  }
223
223
 
224
- const resourceIdRegexp
225
- = /^(?:(?<xx>XX)|(?<rn>[XRN])(?<lg>[XLG])):0x(?<rid>[0-9a-fA-F]+)(?:\[0x(?<txid>[0-9a-fA-F]+)])?$/;
224
+ const resourceIdRegexp =
225
+ /^(?:(?<xx>XX)|(?<rn>[XRN])(?<lg>[XLG])):0x(?<rid>[0-9a-fA-F]+)(?:\[0x(?<txid>[0-9a-fA-F]+)])?$/;
226
226
 
227
227
  export function resourceIdFromString(str: string): OptionalAnyResourceId | undefined {
228
228
  const match = str.match(resourceIdRegexp);
229
229
  if (match === null) return undefined;
230
230
  const { xx, rn, lg, rid, txid } = match.groups!;
231
231
  if (xx) return NullResourceId;
232
- if (lg === 'L')
233
- return createLocalResourceId(rn === 'R', Number.parseInt(rid, 16), Number.parseInt(txid, 16));
234
- else return createGlobalResourceId(rn === 'R', BigInt('0x' + rid));
232
+ if (lg === "L")
233
+ return createLocalResourceId(rn === "R", Number.parseInt(rid, 16), Number.parseInt(txid, 16));
234
+ else return createGlobalResourceId(rn === "R", BigInt("0x" + rid));
235
235
  }
236
236
 
237
237
  /** Converts bigint to global resource id */
@@ -244,6 +244,6 @@ export function bigintToResourceId(resourceId: bigint): ResourceId {
244
244
 
245
245
  export function stringifyWithResourceId(object: unknown): string {
246
246
  return JSON.stringify(object, (key, value) =>
247
- typeof value === 'bigint' ? resourceIdToString(value as OptionalAnyResourceId) : value,
247
+ typeof value === "bigint" ? resourceIdToString(value as OptionalAnyResourceId) : value,
248
248
  );
249
249
  }
@@ -1,28 +1,32 @@
1
- import { UnauthenticatedPlClient } from './unauth_client';
2
- import { getTestConfig, plAddressToTestConfig } from '../test/test_config';
3
- import { UnauthenticatedError } from './errors';
4
- import { test, expect } from 'vitest';
1
+ import { UnauthenticatedPlClient } from "./unauth_client";
2
+ import { getTestConfig, plAddressToTestConfig } from "../test/test_config";
3
+ import { UnauthenticatedError } from "./errors";
4
+ import { test, expect } from "vitest";
5
5
 
6
- test('ping test', async () => {
7
- const client = await UnauthenticatedPlClient.build(plAddressToTestConfig(getTestConfig().address));
6
+ test("ping test", async () => {
7
+ const client = await UnauthenticatedPlClient.build(
8
+ plAddressToTestConfig(getTestConfig().address),
9
+ );
8
10
  const response = await client.ping();
9
- expect(response).toHaveProperty('coreVersion');
11
+ expect(response).toHaveProperty("coreVersion");
10
12
  });
11
13
 
12
- test('get auth methods', async () => {
13
- const client = await UnauthenticatedPlClient.build(plAddressToTestConfig(getTestConfig().address));
14
+ test("get auth methods", async () => {
15
+ const client = await UnauthenticatedPlClient.build(
16
+ plAddressToTestConfig(getTestConfig().address),
17
+ );
14
18
  const response = await client.authMethods();
15
- expect(response).toHaveProperty('methods');
19
+ expect(response).toHaveProperty("methods");
16
20
  });
17
21
 
18
- test('wrong login', async () => {
22
+ test("wrong login", async () => {
19
23
  const testConfig = getTestConfig();
20
24
  if (testConfig.test_user === undefined || testConfig.test_password === undefined) {
21
- console.log('skipped');
25
+ console.log("skipped");
22
26
  return;
23
27
  }
24
28
  const client = await UnauthenticatedPlClient.build(plAddressToTestConfig(testConfig.address));
25
- await expect(client.login(testConfig.test_user, testConfig.test_password + 'A')).rejects.toThrow(
26
- UnauthenticatedError
29
+ await expect(client.login(testConfig.test_user, testConfig.test_password + "A")).rejects.toThrow(
30
+ UnauthenticatedError,
27
31
  );
28
32
  });
@@ -1,11 +1,11 @@
1
- import type { AuthInformation, PlClientConfig } from './config';
1
+ import type { AuthInformation, PlClientConfig } from "./config";
2
2
  import type {
3
3
  AuthAPI_ListMethods_Response,
4
4
  MaintenanceAPI_Ping_Response,
5
- } from '../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api';
6
- import { LLPlClient } from './ll_client';
7
- import { type MiLogger, notEmpty } from '@milaboratories/ts-helpers';
8
- import { UnauthenticatedError } from './errors';
5
+ } from "../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api";
6
+ import { LLPlClient } from "./ll_client";
7
+ import { type MiLogger, notEmpty } from "@milaboratories/ts-helpers";
8
+ import { UnauthenticatedError } from "./errors";
9
9
 
10
10
  /** Primarily used for initial authentication (login) */
11
11
  export class UnauthenticatedPlClient {
@@ -15,7 +15,10 @@ export class UnauthenticatedPlClient {
15
15
  this.ll = ll;
16
16
  }
17
17
 
18
- public static async build(configOrAddress: PlClientConfig | string, ops?: { logger?: MiLogger }): Promise<UnauthenticatedPlClient> {
18
+ public static async build(
19
+ configOrAddress: PlClientConfig | string,
20
+ ops?: { logger?: MiLogger },
21
+ ): Promise<UnauthenticatedPlClient> {
19
22
  const ll = await LLPlClient.build(configOrAddress, ops);
20
23
  return new UnauthenticatedPlClient(ll);
21
24
  }
@@ -34,15 +37,14 @@ export class UnauthenticatedPlClient {
34
37
 
35
38
  public async login(user: string, password: string): Promise<AuthInformation> {
36
39
  try {
37
- const token = await this.ll.getJwtToken(
38
- BigInt(this.ll.conf.authTTLSeconds),
39
- { authorization: 'Basic ' + Buffer.from(user + ':' + password).toString('base64') },
40
- );
40
+ const token = await this.ll.getJwtToken(BigInt(this.ll.conf.authTTLSeconds), {
41
+ authorization: "Basic " + Buffer.from(user + ":" + password).toString("base64"),
42
+ });
41
43
  const jwtToken = notEmpty(token);
42
- if (jwtToken === '') throw new Error('empty token');
44
+ if (jwtToken === "") throw new Error("empty token");
43
45
  return { jwtToken };
44
46
  } catch (e: any) {
45
- if (e.code === 'UNAUTHENTICATED') throw new UnauthenticatedError(e.message);
47
+ if (e.code === "UNAUTHENTICATED") throw new UnauthenticatedError(e.message);
46
48
  throw new Error(e);
47
49
  }
48
50
  }
@@ -1,8 +1,8 @@
1
- import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest';
1
+ import { describe, test, expect, vi, beforeEach, afterEach } from "vitest";
2
2
  import {
3
3
  TxAPI_ClientMessage as ClientMessageType,
4
4
  TxAPI_ServerMessage as ServerMessageType,
5
- } from '../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api';
5
+ } from "../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api";
6
6
 
7
7
  // Mock WebSocket - must be hoisted for vi.mock
8
8
  const MockWebSocket = vi.hoisted(() => {
@@ -13,7 +13,7 @@ const MockWebSocket = vi.hoisted(() => {
13
13
  static CLOSED = 3;
14
14
 
15
15
  readyState = 0;
16
- binaryType = 'blob';
16
+ binaryType = "blob";
17
17
 
18
18
  private listeners: Map<string, Set<Function>> = new Map();
19
19
 
@@ -48,36 +48,36 @@ const MockWebSocket = vi.hoisted(() => {
48
48
  send = vi.fn();
49
49
  close = vi.fn(() => {
50
50
  this.readyState = MockWS.CLOSED;
51
- this.emit('close');
51
+ this.emit("close");
52
52
  });
53
53
 
54
54
  simulateOpen() {
55
55
  this.readyState = MockWS.OPEN;
56
- this.emit('open');
56
+ this.emit("open");
57
57
  }
58
58
 
59
59
  simulateMessage(data: ArrayBuffer) {
60
- this.emit('message', { data });
60
+ this.emit("message", { data });
61
61
  }
62
62
 
63
63
  simulateError(error: Error) {
64
- this.emit('error', error);
64
+ this.emit("error", error);
65
65
  }
66
66
 
67
67
  simulateClose() {
68
68
  this.readyState = MockWS.CLOSED;
69
- this.emit('close');
69
+ this.emit("close");
70
70
  }
71
71
  }
72
72
  return MockWS;
73
73
  });
74
74
 
75
- vi.mock('undici', () => ({
75
+ vi.mock("undici", () => ({
76
76
  WebSocket: MockWebSocket,
77
77
  }));
78
78
 
79
- import { WebSocketBiDiStream } from './websocket_stream';
80
- import type { RetryConfig } from '../helpers/retry_strategy';
79
+ import { WebSocketBiDiStream } from "./websocket_stream";
80
+ import type { RetryConfig } from "../helpers/retry_strategy";
81
81
 
82
82
  type MockWS = InstanceType<typeof MockWebSocket>;
83
83
 
@@ -90,7 +90,7 @@ interface StreamContext {
90
90
  function createStream(token?: string, retryConfig?: Partial<RetryConfig>): StreamContext {
91
91
  const controller = new AbortController();
92
92
  const stream = new WebSocketBiDiStream(
93
- 'ws://localhost:8080',
93
+ "ws://localhost:8080",
94
94
  (message: ClientMessageType) => ClientMessageType.toBinary(message),
95
95
  (data) => ServerMessageType.fromBinary(data),
96
96
  {
@@ -111,7 +111,10 @@ async function openConnection(ws: MockWS): Promise<void> {
111
111
  function createServerMessageBuffer(): ArrayBuffer {
112
112
  const message = ServerMessageType.create({});
113
113
  const binary = ServerMessageType.toBinary(message);
114
- return binary.buffer.slice(binary.byteOffset, binary.byteOffset + binary.byteLength) as ArrayBuffer;
114
+ return binary.buffer.slice(
115
+ binary.byteOffset,
116
+ binary.byteOffset + binary.byteLength,
117
+ ) as ArrayBuffer;
115
118
  }
116
119
 
117
120
  function createClientMessage(): ClientMessageType {
@@ -130,7 +133,7 @@ async function collectMessages(
130
133
  return messages;
131
134
  }
132
135
 
133
- describe('WebSocketBiDiStream', () => {
136
+ describe("WebSocketBiDiStream", () => {
134
137
  beforeEach(() => {
135
138
  vi.useFakeTimers();
136
139
  MockWebSocket.reset();
@@ -140,21 +143,19 @@ describe('WebSocketBiDiStream', () => {
140
143
  vi.useRealTimers();
141
144
  });
142
145
 
143
- describe('constructor', () => {
144
- test('should pass JWT token in authorization header', () => {
145
- createStream('test-token');
146
+ describe("constructor", () => {
147
+ test("should pass JWT token in authorization header", () => {
148
+ createStream("test-token");
146
149
 
147
- expect(MockWebSocket.instances[0].options?.headers?.authorization).toBe(
148
- 'Bearer test-token',
149
- );
150
+ expect(MockWebSocket.instances[0].options?.headers?.authorization).toBe("Bearer test-token");
150
151
  });
151
152
 
152
- test('should not create WebSocket if already aborted', () => {
153
+ test("should not create WebSocket if already aborted", () => {
153
154
  const controller = new AbortController();
154
155
  controller.abort();
155
156
 
156
157
  new WebSocketBiDiStream(
157
- 'ws://localhost:8080',
158
+ "ws://localhost:8080",
158
159
  (message: ClientMessageType) => ClientMessageType.toBinary(message),
159
160
  (data) => ServerMessageType.fromBinary(data),
160
161
  {
@@ -166,8 +167,8 @@ describe('WebSocketBiDiStream', () => {
166
167
  });
167
168
  });
168
169
 
169
- describe('send messages', () => {
170
- test('should queue message and send when connected', async () => {
170
+ describe("send messages", () => {
171
+ test("should queue message and send when connected", async () => {
171
172
  const { stream, ws } = createStream();
172
173
 
173
174
  const sendPromise = stream.requests.send(createClientMessage());
@@ -179,31 +180,31 @@ describe('WebSocketBiDiStream', () => {
179
180
  expect(ws.send).toHaveBeenCalledTimes(1);
180
181
  });
181
182
 
182
- test('should throw error when sending after complete', async () => {
183
+ test("should throw error when sending after complete", async () => {
183
184
  const { stream, ws } = createStream();
184
185
 
185
186
  await openConnection(ws);
186
187
  await stream.requests.complete();
187
188
 
188
189
  await expect(stream.requests.send(createClientMessage())).rejects.toThrow(
189
- 'Cannot send: stream already completed',
190
+ "Cannot send: stream already completed",
190
191
  );
191
192
  });
192
193
 
193
- test('should throw error when sending after abort', async () => {
194
+ test("should throw error when sending after abort", async () => {
194
195
  const { stream, ws, controller } = createStream();
195
196
 
196
197
  await openConnection(ws);
197
198
  controller.abort();
198
199
 
199
200
  await expect(stream.requests.send(createClientMessage())).rejects.toThrow(
200
- 'Cannot send: stream aborted',
201
+ "Cannot send: stream aborted",
201
202
  );
202
203
  });
203
204
  });
204
205
 
205
- describe('receive messages', () => {
206
- test('should receive messages via async iterator', async () => {
206
+ describe("receive messages", () => {
207
+ test("should receive messages via async iterator", async () => {
207
208
  const { stream, ws } = createStream();
208
209
 
209
210
  await openConnection(ws);
@@ -218,7 +219,7 @@ describe('WebSocketBiDiStream', () => {
218
219
  expect(messages).toHaveLength(2);
219
220
  });
220
221
 
221
- test('should buffer messages when no consumer', async () => {
222
+ test("should buffer messages when no consumer", async () => {
222
223
  const { stream, ws } = createStream();
223
224
 
224
225
  await openConnection(ws);
@@ -231,7 +232,7 @@ describe('WebSocketBiDiStream', () => {
231
232
  expect(messages).toHaveLength(2);
232
233
  });
233
234
 
234
- test('should end iterator when stream completes', async () => {
235
+ test("should end iterator when stream completes", async () => {
235
236
  const { stream, ws } = createStream();
236
237
 
237
238
  await openConnection(ws);
@@ -251,8 +252,8 @@ describe('WebSocketBiDiStream', () => {
251
252
  });
252
253
  });
253
254
 
254
- describe('complete', () => {
255
- test('should close WebSocket after complete', async () => {
255
+ describe("complete", () => {
256
+ test("should close WebSocket after complete", async () => {
256
257
  const { stream, ws } = createStream();
257
258
 
258
259
  await openConnection(ws);
@@ -261,7 +262,7 @@ describe('WebSocketBiDiStream', () => {
261
262
  expect(ws.close).toHaveBeenCalled();
262
263
  });
263
264
 
264
- test('should be idempotent', async () => {
265
+ test("should be idempotent", async () => {
265
266
  const { stream, ws } = createStream();
266
267
 
267
268
  await openConnection(ws);
@@ -272,7 +273,7 @@ describe('WebSocketBiDiStream', () => {
272
273
  expect(ws.close).toHaveBeenCalledTimes(1);
273
274
  });
274
275
 
275
- test('should drain send queue before closing', async () => {
276
+ test("should drain send queue before closing", async () => {
276
277
  const { stream, ws } = createStream();
277
278
 
278
279
  const sendPromise1 = stream.requests.send(createClientMessage());
@@ -289,8 +290,8 @@ describe('WebSocketBiDiStream', () => {
289
290
  });
290
291
  });
291
292
 
292
- describe('abort signal', () => {
293
- test('should close stream when aborted', async () => {
293
+ describe("abort signal", () => {
294
+ test("should close stream when aborted", async () => {
294
295
  const { ws, controller } = createStream();
295
296
 
296
297
  await openConnection(ws);
@@ -299,7 +300,7 @@ describe('WebSocketBiDiStream', () => {
299
300
  expect(ws.close).toHaveBeenCalled();
300
301
  });
301
302
 
302
- test('should reject pending sends when aborted', async () => {
303
+ test("should reject pending sends when aborted", async () => {
303
304
  const { stream, controller } = createStream();
304
305
 
305
306
  const sendPromise = stream.requests.send(createClientMessage());
@@ -311,7 +312,7 @@ describe('WebSocketBiDiStream', () => {
311
312
  await expect(sendPromise).rejects.toThrow();
312
313
  });
313
314
 
314
- test('should end response iterator when aborted', async () => {
315
+ test("should end response iterator when aborted", async () => {
315
316
  const { stream, ws, controller } = createStream();
316
317
 
317
318
  await openConnection(ws);
@@ -336,38 +337,38 @@ describe('WebSocketBiDiStream', () => {
336
337
  });
337
338
  });
338
339
 
339
- describe('reconnection', () => {
340
+ describe("reconnection", () => {
340
341
  const retryConfig: Partial<RetryConfig> = {
341
342
  initialDelay: 50,
342
343
  maxDelay: 100,
343
344
  maxAttempts: 5,
344
345
  };
345
346
 
346
- test('should not attempt reconnection on unexpected close', async () => {
347
+ test("should not attempt reconnection on unexpected close", async () => {
347
348
  const { ws } = createStream(undefined, retryConfig);
348
349
 
349
350
  await openConnection(ws);
350
351
 
351
352
  ws.readyState = MockWebSocket.CLOSED;
352
- ws.emit('close');
353
+ ws.emit("close");
353
354
  await vi.advanceTimersByTimeAsync(150);
354
355
 
355
356
  expect(MockWebSocket.instances.length).toBe(1);
356
357
  });
357
358
 
358
- test('should stop reconnecting after max attempts', async () => {
359
+ test("should stop reconnecting after max attempts", async () => {
359
360
  createStream(undefined, { maxAttempts: 3, initialDelay: 10, maxDelay: 100 });
360
361
 
361
362
  for (let i = 0; i < 5; i++) {
362
363
  const ws = MockWebSocket.instances[MockWebSocket.instances.length - 1];
363
- ws.simulateError(new Error('Connection failed'));
364
+ ws.simulateError(new Error("Connection failed"));
364
365
  await vi.advanceTimersByTimeAsync(200);
365
366
  }
366
367
 
367
368
  expect(MockWebSocket.instances.length).toBeLessThanOrEqual(4);
368
369
  });
369
370
 
370
- test('should not reconnect after complete', async () => {
371
+ test("should not reconnect after complete", async () => {
371
372
  const { stream, ws } = createStream();
372
373
 
373
374
  await openConnection(ws);
@@ -378,8 +379,8 @@ describe('WebSocketBiDiStream', () => {
378
379
  });
379
380
  });
380
381
 
381
- describe('error handling', () => {
382
- test('should reject response iterator on parse error', async () => {
382
+ describe("error handling", () => {
383
+ test("should reject response iterator on parse error", async () => {
383
384
  const { stream, ws } = createStream();
384
385
 
385
386
  await openConnection(ws);
@@ -397,7 +398,7 @@ describe('WebSocketBiDiStream', () => {
397
398
  await expect(nextPromise).rejects.toThrow();
398
399
  });
399
400
 
400
- test('should throw on unsupported message format', async () => {
401
+ test("should throw on unsupported message format", async () => {
401
402
  const { stream, ws } = createStream();
402
403
 
403
404
  await openConnection(ws);
@@ -407,17 +408,16 @@ describe('WebSocketBiDiStream', () => {
407
408
  for await (const _ of stream.responses) {
408
409
  // Should not reach here
409
410
  }
410
- return 'completed';
411
+ return "completed";
411
412
  } catch (e) {
412
413
  return e;
413
414
  }
414
415
  })();
415
416
 
416
- ws.emit('message', { data: 'not a buffer' });
417
+ ws.emit("message", { data: "not a buffer" });
417
418
 
418
419
  const result = await iteratorPromise;
419
420
  expect(result).toBeInstanceOf(Error);
420
421
  });
421
422
  });
422
-
423
423
  });