@milaboratories/pl-client 3.2.5 → 3.3.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.
Files changed (112) hide show
  1. package/dist/core/client.cjs +24 -56
  2. package/dist/core/client.cjs.map +1 -1
  3. package/dist/core/client.d.ts +12 -8
  4. package/dist/core/client.d.ts.map +1 -1
  5. package/dist/core/client.js +26 -58
  6. package/dist/core/client.js.map +1 -1
  7. package/dist/core/errors.cjs +20 -0
  8. package/dist/core/errors.cjs.map +1 -1
  9. package/dist/core/errors.d.ts +6 -1
  10. package/dist/core/errors.d.ts.map +1 -1
  11. package/dist/core/errors.js +19 -1
  12. package/dist/core/errors.js.map +1 -1
  13. package/dist/core/final.cjs +6 -5
  14. package/dist/core/final.cjs.map +1 -1
  15. package/dist/core/final.d.ts.map +1 -1
  16. package/dist/core/final.js +7 -6
  17. package/dist/core/final.js.map +1 -1
  18. package/dist/core/ll_client.cjs +18 -1
  19. package/dist/core/ll_client.cjs.map +1 -1
  20. package/dist/core/ll_client.d.ts +6 -2
  21. package/dist/core/ll_client.d.ts.map +1 -1
  22. package/dist/core/ll_client.js +19 -2
  23. package/dist/core/ll_client.js.map +1 -1
  24. package/dist/core/transaction.cjs +109 -75
  25. package/dist/core/transaction.cjs.map +1 -1
  26. package/dist/core/transaction.d.ts +30 -22
  27. package/dist/core/transaction.d.ts.map +1 -1
  28. package/dist/core/transaction.js +111 -76
  29. package/dist/core/transaction.js.map +1 -1
  30. package/dist/core/type_conversion.cjs +14 -6
  31. package/dist/core/type_conversion.cjs.map +1 -1
  32. package/dist/core/type_conversion.js +14 -6
  33. package/dist/core/type_conversion.js.map +1 -1
  34. package/dist/core/types.cjs +77 -17
  35. package/dist/core/types.cjs.map +1 -1
  36. package/dist/core/types.d.ts +49 -26
  37. package/dist/core/types.d.ts.map +1 -1
  38. package/dist/core/types.js +66 -14
  39. package/dist/core/types.js.map +1 -1
  40. package/dist/core/user_resources.cjs +181 -0
  41. package/dist/core/user_resources.cjs.map +1 -0
  42. package/dist/core/user_resources.d.ts +75 -0
  43. package/dist/core/user_resources.d.ts.map +1 -0
  44. package/dist/core/user_resources.js +180 -0
  45. package/dist/core/user_resources.js.map +1 -0
  46. package/dist/helpers/poll.cjs +4 -4
  47. package/dist/helpers/poll.cjs.map +1 -1
  48. package/dist/helpers/poll.d.ts +3 -3
  49. package/dist/helpers/poll.d.ts.map +1 -1
  50. package/dist/helpers/poll.js +5 -5
  51. package/dist/helpers/poll.js.map +1 -1
  52. package/dist/helpers/tx_helpers.cjs +1 -1
  53. package/dist/helpers/tx_helpers.cjs.map +1 -1
  54. package/dist/helpers/tx_helpers.d.ts +3 -3
  55. package/dist/helpers/tx_helpers.d.ts.map +1 -1
  56. package/dist/helpers/tx_helpers.js +2 -2
  57. package/dist/helpers/tx_helpers.js.map +1 -1
  58. package/dist/index.cjs +16 -5
  59. package/dist/index.d.ts +5 -4
  60. package/dist/index.js +5 -4
  61. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.cjs +724 -188
  62. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.cjs.map +1 -1
  63. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.cjs +34 -9
  64. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.cjs.map +1 -1
  65. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.d.ts +37 -5
  66. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.d.ts.map +1 -1
  67. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.js +34 -9
  68. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.js.map +1 -1
  69. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts +326 -136
  70. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts.map +1 -1
  71. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.js +724 -188
  72. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.js.map +1 -1
  73. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.cjs +18 -7
  74. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.cjs.map +1 -1
  75. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.d.ts +11 -7
  76. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.d.ts.map +1 -1
  77. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.js +18 -7
  78. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.js.map +1 -1
  79. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.cjs +57 -2
  80. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.cjs.map +1 -1
  81. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.d.ts +26 -3
  82. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.d.ts.map +1 -1
  83. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.js +57 -3
  84. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.js.map +1 -1
  85. package/dist/proto-rest/plapi.d.ts +421 -207
  86. package/dist/proto-rest/plapi.d.ts.map +1 -1
  87. package/dist/test/test_config.cjs +6 -3
  88. package/dist/test/test_config.cjs.map +1 -1
  89. package/dist/test/test_config.d.ts.map +1 -1
  90. package/dist/test/test_config.js +7 -4
  91. package/dist/test/test_config.js.map +1 -1
  92. package/package.json +5 -5
  93. package/src/core/client.ts +58 -103
  94. package/src/core/errors.ts +23 -0
  95. package/src/core/final.ts +16 -6
  96. package/src/core/ll_client.ts +39 -3
  97. package/src/core/ll_transaction.test.ts +41 -6
  98. package/src/core/transaction.ts +176 -86
  99. package/src/core/type_conversion.ts +24 -9
  100. package/src/core/types.ts +147 -41
  101. package/src/core/user_resources.ts +332 -0
  102. package/src/helpers/poll.ts +15 -8
  103. package/src/helpers/state_helpers.ts +2 -2
  104. package/src/helpers/tx_helpers.ts +5 -5
  105. package/src/index.ts +1 -0
  106. package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.ts +61 -14
  107. package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.ts +1045 -379
  108. package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.ts +33 -18
  109. package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.ts +75 -6
  110. package/src/proto-grpc/google/protobuf/descriptor.ts +5 -2
  111. package/src/proto-rest/plapi.ts +447 -225
  112. package/src/test/test_config.ts +8 -5
package/src/core/final.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Optional } from "utility-types";
2
2
  import type { BasicResourceData, ResourceData } from "./types";
3
- import { getField, isNotNullResourceId, isNullResourceId } from "./types";
3
+ import { getField, isNotNullSignedResourceId, isNullSignedResourceId } from "./types";
4
4
  import { ResourceTypeName, ResourceTypePrefix } from "@milaboratories/pl-model-common";
5
5
  export { ResourceTypeName, ResourceTypePrefix };
6
6
 
@@ -19,7 +19,9 @@ export type FinalResourceDataPredicate = (
19
19
 
20
20
  function readyOrDuplicateOrError(r: ResourceData | BasicResourceData): boolean {
21
21
  return (
22
- r.resourceReady || isNotNullResourceId(r.originalResourceId) || isNotNullResourceId(r.error)
22
+ r.resourceReady ||
23
+ isNotNullSignedResourceId(r.originalResourceId) ||
24
+ isNotNullSignedResourceId(r.error)
23
25
  );
24
26
  }
25
27
 
@@ -28,7 +30,8 @@ function readyAndHasAllOutputsFilled(r: Optional<ResourceData, "fields">): boole
28
30
  if (!r.outputsLocked) return false;
29
31
  if (r.fields === undefined) return true; // if fields are not provided basic resource state is not expected to change in the future
30
32
  for (const f of r.fields)
31
- if (isNullResourceId(f.error) && (isNullResourceId(f.value) || !f.valueIsFinal)) return false;
33
+ if (isNullSignedResourceId(f.error) && (isNullSignedResourceId(f.value) || !f.valueIsFinal))
34
+ return false;
32
35
  return true;
33
36
  }
34
37
 
@@ -41,7 +44,7 @@ export const DefaultFinalResourceDataPredicate: FinalResourceDataPredicate = (r)
41
44
  case ResourceTypeName.StreamManager: {
42
45
  if (!readyOrDuplicateOrError(r)) return false;
43
46
  if (r.fields === undefined) return true; // if fields are not provided basic resource state is not expected to change in the future
44
- if (isNotNullResourceId(r.error)) return true;
47
+ if (isNotNullSignedResourceId(r.error)) return true;
45
48
  const downloadable = getField(r as ResourceData, "downloadable");
46
49
  const stream = getField(r as ResourceData, "stream");
47
50
  return stream.value === downloadable.value;
@@ -79,14 +82,21 @@ export const DefaultFinalResourceDataPredicate: FinalResourceDataPredicate = (r)
79
82
  case ResourceTypeName.Null:
80
83
  case ResourceTypeName.Binary:
81
84
  case ResourceTypeName.LSProvider:
85
+ case ResourceTypeName.WorkingDirectory:
82
86
  return true;
83
87
  case ResourceTypeName.UserProject:
84
88
  case ResourceTypeName.Projects:
85
89
  case ResourceTypeName.ClientRoot:
86
90
  return false;
87
91
  default:
88
- if (r.type.name.startsWith(ResourceTypePrefix.Blob)) return true;
89
- else if (
92
+ if (
93
+ r.type.name.startsWith(ResourceTypePrefix.Blob) ||
94
+ r.type.name.startsWith(ResourceTypePrefix.LS) ||
95
+ r.type.name.startsWith(ResourceTypePrefix.WorkingDirectory) ||
96
+ r.type.name.startsWith(ResourceTypePrefix.StorageSpaceAllocation)
97
+ ) {
98
+ return true;
99
+ } else if (
90
100
  r.type.name.startsWith(ResourceTypePrefix.BlobUpload) ||
91
101
  r.type.name.startsWith(ResourceTypePrefix.BlobIndex)
92
102
  ) {
@@ -35,7 +35,7 @@ import { notEmpty, retry, withTimeout, type RetryOptions } from "@milaboratories
35
35
  import { Code } from "../proto-grpc/google/rpc/code";
36
36
  import { WebSocketBiDiStream } from "./websocket_stream";
37
37
  import {
38
- AuthAPI_GetJWTToken_Role,
38
+ AuthAPI_Role,
39
39
  TxAPI_ClientMessage,
40
40
  TxAPI_ServerMessage,
41
41
  } from "../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api";
@@ -463,10 +463,10 @@ export class LLPlClient implements WireClientProviderFactory {
463
463
 
464
464
  public async getJwtToken(
465
465
  ttlSeconds: bigint,
466
- options?: { authorization?: string; role?: AuthAPI_GetJWTToken_Role },
466
+ options?: { authorization?: string; role?: AuthAPI_Role },
467
467
  ): Promise<string> {
468
468
  const cl = this.clientProvider.get();
469
- const role = options?.role ?? AuthAPI_GetJWTToken_Role.ROLE_UNSPECIFIED;
469
+ const role = options?.role ?? AuthAPI_Role.UNSPECIFIED;
470
470
 
471
471
  if (cl instanceof GrpcPlApiClient) {
472
472
  const meta: Record<string, string> = {};
@@ -592,6 +592,42 @@ export class LLPlClient implements WireClientProviderFactory {
592
592
  }
593
593
  }
594
594
 
595
+ public async getUserRoot(
596
+ opts: { login?: string; doNotCreate?: boolean } = {},
597
+ ): Promise<grpcTypes.AuthAPI_GetUserRoot_Response> {
598
+ const cl = this.clientProvider.get();
599
+ if (cl instanceof GrpcPlApiClient) {
600
+ return (
601
+ await cl.getUserRoot({
602
+ login: opts.login ?? "",
603
+ doNotCreate: opts.doNotCreate ?? false,
604
+ })
605
+ ).response;
606
+ } else {
607
+ const resp = notEmpty(
608
+ (
609
+ await cl.POST("/v1/auth/user-root", {
610
+ body: {
611
+ login: opts.login ?? "",
612
+ doNotCreate: opts.doNotCreate ?? false,
613
+ },
614
+ })
615
+ ).data,
616
+ "REST: empty response for getUserRoot request",
617
+ );
618
+ return {
619
+ userRoot: resp.userRoot
620
+ ? {
621
+ resourceId: BigInt(resp.userRoot.resourceId),
622
+ resourceSignature: Uint8Array.from(
623
+ Buffer.from(resp.userRoot.resourceSignature, "base64"),
624
+ ),
625
+ }
626
+ : undefined,
627
+ };
628
+ }
629
+ }
630
+
595
631
  public async listUserResources(
596
632
  opts: { login?: string; startFrom?: bigint; limit?: number } = {},
597
633
  ): Promise<grpcTypes.AuthAPI_ListUserResources_Response[]> {
@@ -6,6 +6,23 @@ import { test, expect } from "vitest";
6
6
  import { isTimeoutOrCancelError } from "./errors";
7
7
  import { Aborted } from "@milaboratories/ts-helpers";
8
8
 
9
+ /** Cached root signature — fetched once, shared across tests. */
10
+ let cachedRootSig: Uint8Array | undefined;
11
+
12
+ async function getRootSignature(): Promise<Uint8Array> {
13
+ if (cachedRootSig !== undefined) return cachedRootSig;
14
+ const client = await getTestLLClient();
15
+ const responses = await client.listUserResources({ limit: 1 });
16
+ for (const msg of responses) {
17
+ if (msg.entry.oneofKind === "userRoot" && msg.entry.userRoot.resourceSignature) {
18
+ cachedRootSig = msg.entry.userRoot.resourceSignature;
19
+ return cachedRootSig;
20
+ }
21
+ }
22
+ cachedRootSig = new Uint8Array(0);
23
+ return cachedRootSig;
24
+ }
25
+
9
26
  test("check successful transaction", async () => {
10
27
  const client = await getTestLLClient();
11
28
  const tx = client.createTx(true);
@@ -80,6 +97,7 @@ test("check timeout error type (passive)", async () => {
80
97
 
81
98
  test("check timeout error type (active)", async () => {
82
99
  const client = await getTestLLClient();
100
+ const rootSig = await getRootSignature();
83
101
  const tx = client.createTx(true, { timeout: 500 });
84
102
 
85
103
  try {
@@ -96,6 +114,12 @@ test("check timeout error type (active)", async () => {
96
114
  );
97
115
  expect(openResponse.txOpen.tx?.isValid).toBeTruthy();
98
116
 
117
+ // Set default color so resource creation succeeds in strict mode
118
+ await tx.send(
119
+ { oneofKind: "setDefaultColor", setDefaultColor: { colorProof: rootSig } },
120
+ false,
121
+ );
122
+
99
123
  const rData = Uint8Array.from([
100
124
  (Math.random() * 256) & 0xff,
101
125
  (Math.random() * 256) & 0xff,
@@ -112,15 +136,17 @@ test("check timeout error type (active)", async () => {
112
136
  oneofKind: "resourceCreateValue",
113
137
  resourceCreateValue: {
114
138
  id: createLocalResourceId(false, 1, 1),
139
+ colorProof: new Uint8Array(0),
115
140
  type: { name: "TestValue", version: "1" },
116
141
  data: rData,
117
142
  errorIfExists: false,
118
- colorProof: new Uint8Array(0),
119
143
  },
120
144
  },
121
145
  false,
122
146
  );
123
- const id = (await createResponse).resourceCreateValue.resourceId;
147
+ const createResp = (await createResponse).resourceCreateValue;
148
+ const id = createResp.resourceId;
149
+ const resourceSignature = createResp.resourceSignature ?? new Uint8Array(0);
124
150
 
125
151
  while (true) {
126
152
  const vr = await tx.send(
@@ -129,7 +155,7 @@ test("check timeout error type (active)", async () => {
129
155
  resourceGet: {
130
156
  resourceId: id,
131
157
  loadFields: false,
132
- resourceSignature: new Uint8Array(0),
158
+ resourceSignature,
133
159
  },
134
160
  },
135
161
  false,
@@ -144,6 +170,7 @@ test("check timeout error type (active)", async () => {
144
170
 
145
171
  test("check is abort error (active)", async () => {
146
172
  const client = await getTestLLClient();
173
+ const rootSig = await getRootSignature();
147
174
  const tx = client.createTx(true, { abortSignal: AbortSignal.timeout(100) });
148
175
 
149
176
  try {
@@ -160,6 +187,12 @@ test("check is abort error (active)", async () => {
160
187
  );
161
188
  expect(openResponse.txOpen.tx?.isValid).toBeTruthy();
162
189
 
190
+ // Set default color so resource creation succeeds in strict mode
191
+ await tx.send(
192
+ { oneofKind: "setDefaultColor", setDefaultColor: { colorProof: rootSig } },
193
+ false,
194
+ );
195
+
163
196
  const rData = Uint8Array.from([
164
197
  Math.random() & 0xff,
165
198
  Math.random() & 0xff,
@@ -178,13 +211,15 @@ test("check is abort error (active)", async () => {
178
211
  id: createLocalResourceId(false, 1, 1),
179
212
  type: { name: "TestValue", version: "1" },
180
213
  data: rData,
181
- errorIfExists: false,
182
214
  colorProof: new Uint8Array(0),
215
+ errorIfExists: false,
183
216
  },
184
217
  },
185
218
  false,
186
219
  );
187
- const id = (await createResponse).resourceCreateValue.resourceId;
220
+ const createResp = (await createResponse).resourceCreateValue;
221
+ const id = createResp.resourceId;
222
+ const resourceSignature = createResp.resourceSignature ?? new Uint8Array(0);
188
223
 
189
224
  while (true) {
190
225
  const vr = await tx.send(
@@ -193,7 +228,7 @@ test("check is abort error (active)", async () => {
193
228
  resourceGet: {
194
229
  resourceId: id,
195
230
  loadFields: false,
196
- resourceSignature: new Uint8Array(0),
231
+ resourceSignature,
197
232
  },
198
233
  },
199
234
  false,