@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.
- package/dist/core/client.cjs +24 -56
- package/dist/core/client.cjs.map +1 -1
- package/dist/core/client.d.ts +12 -8
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +26 -58
- package/dist/core/client.js.map +1 -1
- package/dist/core/errors.cjs +20 -0
- package/dist/core/errors.cjs.map +1 -1
- package/dist/core/errors.d.ts +6 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +19 -1
- package/dist/core/errors.js.map +1 -1
- package/dist/core/final.cjs +6 -5
- package/dist/core/final.cjs.map +1 -1
- package/dist/core/final.d.ts.map +1 -1
- package/dist/core/final.js +7 -6
- package/dist/core/final.js.map +1 -1
- package/dist/core/ll_client.cjs +18 -1
- package/dist/core/ll_client.cjs.map +1 -1
- package/dist/core/ll_client.d.ts +6 -2
- package/dist/core/ll_client.d.ts.map +1 -1
- package/dist/core/ll_client.js +19 -2
- package/dist/core/ll_client.js.map +1 -1
- package/dist/core/transaction.cjs +109 -75
- package/dist/core/transaction.cjs.map +1 -1
- package/dist/core/transaction.d.ts +30 -22
- package/dist/core/transaction.d.ts.map +1 -1
- package/dist/core/transaction.js +111 -76
- package/dist/core/transaction.js.map +1 -1
- package/dist/core/type_conversion.cjs +14 -6
- package/dist/core/type_conversion.cjs.map +1 -1
- package/dist/core/type_conversion.js +14 -6
- package/dist/core/type_conversion.js.map +1 -1
- package/dist/core/types.cjs +77 -17
- package/dist/core/types.cjs.map +1 -1
- package/dist/core/types.d.ts +49 -26
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +66 -14
- package/dist/core/types.js.map +1 -1
- package/dist/core/user_resources.cjs +181 -0
- package/dist/core/user_resources.cjs.map +1 -0
- package/dist/core/user_resources.d.ts +75 -0
- package/dist/core/user_resources.d.ts.map +1 -0
- package/dist/core/user_resources.js +180 -0
- package/dist/core/user_resources.js.map +1 -0
- package/dist/helpers/poll.cjs +4 -4
- package/dist/helpers/poll.cjs.map +1 -1
- package/dist/helpers/poll.d.ts +3 -3
- package/dist/helpers/poll.d.ts.map +1 -1
- package/dist/helpers/poll.js +5 -5
- package/dist/helpers/poll.js.map +1 -1
- package/dist/helpers/tx_helpers.cjs +1 -1
- package/dist/helpers/tx_helpers.cjs.map +1 -1
- package/dist/helpers/tx_helpers.d.ts +3 -3
- package/dist/helpers/tx_helpers.d.ts.map +1 -1
- package/dist/helpers/tx_helpers.js +2 -2
- package/dist/helpers/tx_helpers.js.map +1 -1
- package/dist/index.cjs +16 -5
- package/dist/index.d.ts +5 -4
- package/dist/index.js +5 -4
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.cjs +724 -188
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.cjs +34 -9
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.d.ts +37 -5
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.d.ts.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.js +34 -9
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts +326 -136
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.js +724 -188
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.cjs +18 -7
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.d.ts +11 -7
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.d.ts.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.js +18 -7
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.cjs +57 -2
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.d.ts +26 -3
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.d.ts.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.js +57 -3
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.js.map +1 -1
- package/dist/proto-rest/plapi.d.ts +421 -207
- package/dist/proto-rest/plapi.d.ts.map +1 -1
- package/dist/test/test_config.cjs +6 -3
- package/dist/test/test_config.cjs.map +1 -1
- package/dist/test/test_config.d.ts.map +1 -1
- package/dist/test/test_config.js +7 -4
- package/dist/test/test_config.js.map +1 -1
- package/package.json +5 -5
- package/src/core/client.ts +58 -103
- package/src/core/errors.ts +23 -0
- package/src/core/final.ts +16 -6
- package/src/core/ll_client.ts +39 -3
- package/src/core/ll_transaction.test.ts +41 -6
- package/src/core/transaction.ts +176 -86
- package/src/core/type_conversion.ts +24 -9
- package/src/core/types.ts +147 -41
- package/src/core/user_resources.ts +332 -0
- package/src/helpers/poll.ts +15 -8
- package/src/helpers/state_helpers.ts +2 -2
- package/src/helpers/tx_helpers.ts +5 -5
- package/src/index.ts +1 -0
- package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.ts +61 -14
- package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.ts +1045 -379
- package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.ts +33 -18
- package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.ts +75 -6
- package/src/proto-grpc/google/protobuf/descriptor.ts +5 -2
- package/src/proto-rest/plapi.ts +447 -225
- package/src/test/test_config.ts +8 -5
package/src/core/transaction.ts
CHANGED
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
// TODO: fix this
|
|
2
2
|
/* eslint-disable no-prototype-builtins */
|
|
3
3
|
import type {
|
|
4
|
-
|
|
4
|
+
ColorProof,
|
|
5
5
|
LocalResourceId,
|
|
6
|
-
|
|
6
|
+
OptionalSignedResourceId,
|
|
7
7
|
BasicResourceData,
|
|
8
8
|
FieldData,
|
|
9
9
|
FieldType,
|
|
10
10
|
ResourceData,
|
|
11
|
-
|
|
11
|
+
SignedResourceId,
|
|
12
|
+
ResourceSignature,
|
|
12
13
|
ResourceType,
|
|
13
14
|
FutureFieldType,
|
|
14
15
|
} from "./types";
|
|
15
16
|
import {
|
|
17
|
+
createSignedResourceId,
|
|
16
18
|
createLocalResourceId,
|
|
17
|
-
ensureResourceIdNotNull,
|
|
18
|
-
MaxTxId,
|
|
19
19
|
isLocalResourceId,
|
|
20
|
+
ensureSignedResourceIdNotNull,
|
|
21
|
+
MaxTxId,
|
|
20
22
|
extractBasicResourceData,
|
|
21
|
-
|
|
23
|
+
parseSignedResourceId,
|
|
24
|
+
toResourceSignature,
|
|
25
|
+
isSignedResourceId,
|
|
22
26
|
} from "./types";
|
|
23
27
|
import type {
|
|
24
28
|
ClientMessageRequest,
|
|
@@ -51,7 +55,7 @@ import { PromiseTracker } from "./PromiseTracker";
|
|
|
51
55
|
export interface ResourceRef {
|
|
52
56
|
/** Global resource id of newly created resources, become available only
|
|
53
57
|
* after response for the corresponding creation request is received. */
|
|
54
|
-
readonly globalId: Promise<
|
|
58
|
+
readonly globalId: Promise<SignedResourceId>;
|
|
55
59
|
|
|
56
60
|
/** Transaction-local resource id is assigned right after resource creation
|
|
57
61
|
* request is sent, and can be used right away */
|
|
@@ -77,12 +81,12 @@ interface _FieldId<RId> {
|
|
|
77
81
|
fieldName: string;
|
|
78
82
|
}
|
|
79
83
|
|
|
80
|
-
export type FieldId = _FieldId<
|
|
84
|
+
export type FieldId = _FieldId<SignedResourceId>;
|
|
81
85
|
export type FieldRef = _FieldId<ResourceRef>;
|
|
82
86
|
export type LocalFieldId = _FieldId<LocalResourceId>;
|
|
83
87
|
export type AnyFieldId = FieldId | LocalFieldId;
|
|
84
88
|
|
|
85
|
-
export type AnyResourceRef = ResourceRef |
|
|
89
|
+
export type AnyResourceRef = ResourceRef | LocalResourceId | SignedResourceId;
|
|
86
90
|
export type AnyFieldRef = _FieldId<AnyResourceRef>; // FieldRef | FieldId
|
|
87
91
|
export type AnyRef = AnyResourceRef | AnyFieldRef;
|
|
88
92
|
|
|
@@ -91,21 +95,26 @@ export function isField(ref: AnyRef): ref is AnyFieldRef {
|
|
|
91
95
|
}
|
|
92
96
|
|
|
93
97
|
export function isResource(ref: AnyRef): ref is AnyResourceRef {
|
|
94
|
-
return
|
|
95
|
-
|
|
96
|
-
);
|
|
98
|
+
if (typeof ref === "bigint") return true; // LocalResourceId
|
|
99
|
+
if (typeof ref === "string") return true; // SignedResourceId
|
|
100
|
+
return isResourceRef(ref);
|
|
97
101
|
}
|
|
98
102
|
|
|
99
|
-
export function isResourceId(ref: AnyRef): ref is
|
|
100
|
-
return typeof ref === "
|
|
103
|
+
export function isResourceId(ref: AnyRef): ref is SignedResourceId {
|
|
104
|
+
return typeof ref === "string" && isSignedResourceId(ref);
|
|
101
105
|
}
|
|
102
106
|
|
|
103
107
|
export function isFieldRef(ref: AnyFieldRef): ref is FieldRef {
|
|
104
108
|
return isResourceRef(ref.resourceId);
|
|
105
109
|
}
|
|
106
110
|
|
|
107
|
-
export function isResourceRef(ref:
|
|
108
|
-
return
|
|
111
|
+
export function isResourceRef(ref: AnyRef): ref is ResourceRef {
|
|
112
|
+
return (
|
|
113
|
+
typeof ref === "object" &&
|
|
114
|
+
ref !== null &&
|
|
115
|
+
ref.hasOwnProperty("globalId") &&
|
|
116
|
+
ref.hasOwnProperty("localId")
|
|
117
|
+
);
|
|
109
118
|
}
|
|
110
119
|
|
|
111
120
|
export function toFieldId(ref: AnyFieldRef): AnyFieldId {
|
|
@@ -113,20 +122,37 @@ export function toFieldId(ref: AnyFieldRef): AnyFieldId {
|
|
|
113
122
|
else return ref as FieldId;
|
|
114
123
|
}
|
|
115
124
|
|
|
116
|
-
export async function toGlobalFieldId(ref:
|
|
125
|
+
export async function toGlobalFieldId(ref: FieldRef | FieldId): Promise<FieldId> {
|
|
117
126
|
if (isFieldRef(ref))
|
|
118
127
|
return { resourceId: await ref.resourceId.globalId, fieldName: ref.fieldName };
|
|
119
|
-
|
|
128
|
+
return ref;
|
|
120
129
|
}
|
|
121
130
|
|
|
122
|
-
export
|
|
123
|
-
|
|
124
|
-
|
|
131
|
+
export interface ResourceIdWithSignature {
|
|
132
|
+
resourceId: bigint;
|
|
133
|
+
resourceSignature: ResourceSignature;
|
|
125
134
|
}
|
|
126
135
|
|
|
127
|
-
|
|
136
|
+
const emptySignature = toResourceSignature(new Uint8Array(0));
|
|
137
|
+
|
|
138
|
+
function toResourceIdAndSignature(ref: AnyResourceRef): ResourceIdWithSignature {
|
|
139
|
+
if (isResourceRef(ref)) {
|
|
140
|
+
// Local ID — no signature yet
|
|
141
|
+
return { resourceId: ref.localId, resourceSignature: emptySignature };
|
|
142
|
+
}
|
|
143
|
+
if (isResourceId(ref)) {
|
|
144
|
+
// SignedResourceId — decompose
|
|
145
|
+
const { globalId, signature } = parseSignedResourceId(ref);
|
|
146
|
+
return { resourceId: globalId as bigint, resourceSignature: signature };
|
|
147
|
+
}
|
|
148
|
+
// Raw bigint (LocalResourceId)
|
|
149
|
+
return { resourceId: ref as bigint, resourceSignature: emptySignature };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export async function toGlobalResourceId(ref: AnyResourceRef): Promise<SignedResourceId> {
|
|
128
153
|
if (isResourceRef(ref)) return await ref.globalId;
|
|
129
|
-
|
|
154
|
+
if (isLocalResourceId(ref)) return createSignedResourceId(ref); // legacy path: loose security mode in backend
|
|
155
|
+
return ref;
|
|
130
156
|
}
|
|
131
157
|
|
|
132
158
|
export function field(resourceId: AnyResourceRef, fieldName: string): AnyFieldRef {
|
|
@@ -186,9 +212,9 @@ export class PlTransaction {
|
|
|
186
212
|
private readonly ll: LLPlTransaction,
|
|
187
213
|
public readonly name: string,
|
|
188
214
|
public readonly writable: boolean,
|
|
189
|
-
private readonly _clientRoot:
|
|
215
|
+
private readonly _clientRoot: OptionalSignedResourceId,
|
|
190
216
|
private readonly finalPredicate: FinalResourceDataPredicate,
|
|
191
|
-
private readonly sharedResourceDataCache: LRUCache<
|
|
217
|
+
private readonly sharedResourceDataCache: LRUCache<SignedResourceId, ResourceDataCacheRecord>,
|
|
192
218
|
private readonly enableFormattedErrors: boolean = false,
|
|
193
219
|
) {
|
|
194
220
|
// initiating transaction
|
|
@@ -276,6 +302,40 @@ export class PlTransaction {
|
|
|
276
302
|
void this.track(this.sendVoidSync(r));
|
|
277
303
|
}
|
|
278
304
|
|
|
305
|
+
/** Set default color proof for subsequent resource creation requests */
|
|
306
|
+
public setDefaultColor(colorProof: ColorProof): void {
|
|
307
|
+
this.sendVoidAsync({
|
|
308
|
+
oneofKind: "setDefaultColor",
|
|
309
|
+
setDefaultColor: { colorProof },
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
private toSignedResourceId(rId: AnyResourceRef): ResourceIdWithSignature {
|
|
314
|
+
return toResourceIdAndSignature(rId);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
private toSignedFieldId(fId: AnyFieldRef): {
|
|
318
|
+
resourceId: bigint;
|
|
319
|
+
resourceSignature: ResourceSignature;
|
|
320
|
+
fieldName: string;
|
|
321
|
+
} {
|
|
322
|
+
const base = toFieldId(fId);
|
|
323
|
+
const signed = toResourceIdAndSignature(base.resourceId);
|
|
324
|
+
return {
|
|
325
|
+
resourceId: signed.resourceId,
|
|
326
|
+
fieldName: base.fieldName,
|
|
327
|
+
resourceSignature: signed.resourceSignature,
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
private toSignedErrorRef(rId: AnyResourceRef): {
|
|
332
|
+
errorResourceId: bigint;
|
|
333
|
+
errorResourceSignature: ResourceSignature;
|
|
334
|
+
} {
|
|
335
|
+
const { resourceId, resourceSignature } = this.toSignedResourceId(rId);
|
|
336
|
+
return { errorResourceId: resourceId, errorResourceSignature: resourceSignature };
|
|
337
|
+
}
|
|
338
|
+
|
|
279
339
|
private checkTxOpen() {
|
|
280
340
|
if (this._completed) throw new Error("Transaction already closed");
|
|
281
341
|
}
|
|
@@ -343,8 +403,8 @@ export class PlTransaction {
|
|
|
343
403
|
// Main tx methods
|
|
344
404
|
//
|
|
345
405
|
|
|
346
|
-
public get clientRoot():
|
|
347
|
-
return
|
|
406
|
+
public get clientRoot(): SignedResourceId {
|
|
407
|
+
return ensureSignedResourceIdNotNull(this._clientRoot);
|
|
348
408
|
}
|
|
349
409
|
|
|
350
410
|
//
|
|
@@ -355,26 +415,23 @@ export class PlTransaction {
|
|
|
355
415
|
name: string,
|
|
356
416
|
type: ResourceType,
|
|
357
417
|
errorIfExists: boolean = false,
|
|
418
|
+
color?: ColorProof,
|
|
358
419
|
): ResourceRef {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
{
|
|
420
|
+
return this.createResource(
|
|
421
|
+
false,
|
|
422
|
+
(localId) => ({
|
|
363
423
|
oneofKind: "resourceCreateSingleton",
|
|
364
424
|
resourceCreateSingleton: {
|
|
365
425
|
type,
|
|
366
426
|
id: localId,
|
|
367
427
|
data: Buffer.from(name),
|
|
368
428
|
errorIfExists,
|
|
369
|
-
colorProof:
|
|
429
|
+
colorProof: color ?? emptySignature,
|
|
370
430
|
},
|
|
371
|
-
},
|
|
372
|
-
(r) => r.resourceCreateSingleton.resourceId
|
|
431
|
+
}),
|
|
432
|
+
(r) => r.resourceCreateSingleton.resourceId,
|
|
433
|
+
(r) => r.resourceCreateSingleton.resourceSignature,
|
|
373
434
|
);
|
|
374
|
-
|
|
375
|
-
void this.track(globalId);
|
|
376
|
-
|
|
377
|
-
return { globalId, localId };
|
|
378
435
|
}
|
|
379
436
|
|
|
380
437
|
public getSingleton(name: string, loadFields: true): Promise<ResourceData>;
|
|
@@ -399,10 +456,15 @@ export class PlTransaction {
|
|
|
399
456
|
root: boolean,
|
|
400
457
|
req: (localId: LocalResourceId) => OneOfKind<ClientMessageRequest, Kind>,
|
|
401
458
|
parser: (resp: OneOfKind<ServerMessageResponse, Kind>) => bigint,
|
|
459
|
+
sigExtractor: (resp: OneOfKind<ServerMessageResponse, Kind>) => Uint8Array | undefined,
|
|
402
460
|
): ResourceRef {
|
|
403
461
|
const localId = this.nextLocalResourceId(root);
|
|
404
462
|
|
|
405
|
-
const globalId = this.sendSingleAndParse(req(localId), (r) =>
|
|
463
|
+
const globalId = this.sendSingleAndParse(req(localId), (r) => {
|
|
464
|
+
const rawId = parser(r);
|
|
465
|
+
const sig = sigExtractor ? toResourceSignature(sigExtractor(r)) : undefined;
|
|
466
|
+
return createSignedResourceId(rawId, sig);
|
|
467
|
+
});
|
|
406
468
|
|
|
407
469
|
void this.track(globalId);
|
|
408
470
|
|
|
@@ -415,10 +477,15 @@ export class PlTransaction {
|
|
|
415
477
|
true,
|
|
416
478
|
(localId) => ({ oneofKind: "resourceCreateRoot", resourceCreateRoot: { type, id: localId } }),
|
|
417
479
|
(r) => r.resourceCreateRoot.resourceId,
|
|
480
|
+
(r) => r.resourceCreateRoot.resourceSignature,
|
|
418
481
|
);
|
|
419
482
|
}
|
|
420
483
|
|
|
421
|
-
public createStruct(
|
|
484
|
+
public createStruct(
|
|
485
|
+
type: ResourceType,
|
|
486
|
+
data?: Uint8Array | string,
|
|
487
|
+
color?: ColorProof,
|
|
488
|
+
): ResourceRef {
|
|
422
489
|
this._stat.structsCreated++;
|
|
423
490
|
this._stat.structsCreatedDataBytes += data?.length ?? 0;
|
|
424
491
|
return this.createResource(
|
|
@@ -430,14 +497,19 @@ export class PlTransaction {
|
|
|
430
497
|
id: localId,
|
|
431
498
|
data:
|
|
432
499
|
data === undefined ? undefined : typeof data === "string" ? Buffer.from(data) : data,
|
|
433
|
-
colorProof:
|
|
500
|
+
colorProof: color ?? emptySignature,
|
|
434
501
|
},
|
|
435
502
|
}),
|
|
436
503
|
(r) => r.resourceCreateStruct.resourceId,
|
|
504
|
+
(r) => r.resourceCreateStruct.resourceSignature,
|
|
437
505
|
);
|
|
438
506
|
}
|
|
439
507
|
|
|
440
|
-
public createEphemeral(
|
|
508
|
+
public createEphemeral(
|
|
509
|
+
type: ResourceType,
|
|
510
|
+
data?: Uint8Array | string,
|
|
511
|
+
color?: ColorProof,
|
|
512
|
+
): ResourceRef {
|
|
441
513
|
this._stat.ephemeralsCreated++;
|
|
442
514
|
this._stat.ephemeralsCreatedDataBytes += data?.length ?? 0;
|
|
443
515
|
return this.createResource(
|
|
@@ -449,10 +521,11 @@ export class PlTransaction {
|
|
|
449
521
|
id: localId,
|
|
450
522
|
data:
|
|
451
523
|
data === undefined ? undefined : typeof data === "string" ? Buffer.from(data) : data,
|
|
452
|
-
colorProof:
|
|
524
|
+
colorProof: color ?? emptySignature,
|
|
453
525
|
},
|
|
454
526
|
}),
|
|
455
527
|
(r) => r.resourceCreateEphemeral.resourceId,
|
|
528
|
+
(r) => r.resourceCreateEphemeral.resourceSignature,
|
|
456
529
|
);
|
|
457
530
|
}
|
|
458
531
|
|
|
@@ -460,6 +533,7 @@ export class PlTransaction {
|
|
|
460
533
|
type: ResourceType,
|
|
461
534
|
data: Uint8Array | string,
|
|
462
535
|
errorIfExists: boolean = false,
|
|
536
|
+
color?: ColorProof,
|
|
463
537
|
): ResourceRef {
|
|
464
538
|
this._stat.valuesCreated++;
|
|
465
539
|
this._stat.valuesCreatedDataBytes += data?.length ?? 0;
|
|
@@ -472,34 +546,41 @@ export class PlTransaction {
|
|
|
472
546
|
id: localId,
|
|
473
547
|
data: typeof data === "string" ? Buffer.from(data) : data,
|
|
474
548
|
errorIfExists,
|
|
475
|
-
colorProof:
|
|
549
|
+
colorProof: color ?? emptySignature,
|
|
476
550
|
},
|
|
477
551
|
}),
|
|
478
552
|
(r) => r.resourceCreateValue.resourceId,
|
|
553
|
+
(r) => r.resourceCreateValue.resourceSignature,
|
|
479
554
|
);
|
|
480
555
|
}
|
|
481
556
|
|
|
482
|
-
public createJsonValue(data: unknown): ResourceRef {
|
|
557
|
+
public createJsonValue(data: unknown, color?: ColorProof): ResourceRef {
|
|
483
558
|
const jsonData = canonicalJsonBytes(data);
|
|
484
|
-
return this.createValue(JsonObject, jsonData, false);
|
|
559
|
+
return this.createValue(JsonObject, jsonData, false, color);
|
|
485
560
|
}
|
|
486
561
|
|
|
487
|
-
public createJsonGzValue(
|
|
562
|
+
public createJsonGzValue(
|
|
563
|
+
data: unknown,
|
|
564
|
+
minSizeToGzip: number | undefined = 16_384,
|
|
565
|
+
color?: ColorProof,
|
|
566
|
+
): ResourceRef {
|
|
488
567
|
const { data: jsonData, isGzipped } = canonicalJsonGzBytes(data, minSizeToGzip);
|
|
489
|
-
return this.createValue(isGzipped ? JsonGzObject : JsonObject, jsonData, false);
|
|
568
|
+
return this.createValue(isGzipped ? JsonGzObject : JsonObject, jsonData, false, color);
|
|
490
569
|
}
|
|
491
570
|
|
|
492
|
-
public createError(message: string): ResourceRef {
|
|
571
|
+
public createError(message: string, color?: ColorProof): ResourceRef {
|
|
493
572
|
return this.createValue(
|
|
494
573
|
ErrorResourceType,
|
|
495
574
|
JSON.stringify({ message } satisfies ErrorResourceData),
|
|
575
|
+
false,
|
|
576
|
+
color,
|
|
496
577
|
);
|
|
497
578
|
}
|
|
498
579
|
|
|
499
580
|
public setResourceName(name: string, rId: AnyResourceRef): void {
|
|
500
581
|
this.sendVoidAsync({
|
|
501
582
|
oneofKind: "resourceNameSet",
|
|
502
|
-
resourceNameSet: {
|
|
583
|
+
resourceNameSet: { ...this.toSignedResourceId(rId), name },
|
|
503
584
|
});
|
|
504
585
|
}
|
|
505
586
|
|
|
@@ -507,10 +588,15 @@ export class PlTransaction {
|
|
|
507
588
|
this.sendVoidAsync({ oneofKind: "resourceNameDelete", resourceNameDelete: { name } });
|
|
508
589
|
}
|
|
509
590
|
|
|
510
|
-
public getResourceByName(name: string): Promise<
|
|
591
|
+
public getResourceByName(name: string): Promise<SignedResourceId> {
|
|
511
592
|
return this.sendSingleAndParse(
|
|
512
593
|
{ oneofKind: "resourceNameGet", resourceNameGet: { name } },
|
|
513
|
-
(r) =>
|
|
594
|
+
(r) => {
|
|
595
|
+
const rawId = r.resourceNameGet.resourceId;
|
|
596
|
+
if (rawId === 0n) throw new Error("null resource id from getResourceByName");
|
|
597
|
+
const sig = toResourceSignature(r.resourceNameGet.resourceSignature);
|
|
598
|
+
return createSignedResourceId(rawId, sig);
|
|
599
|
+
},
|
|
514
600
|
);
|
|
515
601
|
}
|
|
516
602
|
|
|
@@ -521,18 +607,18 @@ export class PlTransaction {
|
|
|
521
607
|
);
|
|
522
608
|
}
|
|
523
609
|
|
|
524
|
-
public removeResource(rId:
|
|
610
|
+
public removeResource(rId: SignedResourceId): void {
|
|
525
611
|
this.sendVoidAsync({
|
|
526
612
|
oneofKind: "resourceRemove",
|
|
527
|
-
resourceRemove:
|
|
613
|
+
resourceRemove: this.toSignedResourceId(rId),
|
|
528
614
|
});
|
|
529
615
|
}
|
|
530
616
|
|
|
531
|
-
public resourceExists(rId:
|
|
617
|
+
public resourceExists(rId: SignedResourceId): Promise<boolean> {
|
|
532
618
|
return this.sendSingleAndParse(
|
|
533
619
|
{
|
|
534
620
|
oneofKind: "resourceExists",
|
|
535
|
-
resourceExists:
|
|
621
|
+
resourceExists: this.toSignedResourceId(rId),
|
|
536
622
|
},
|
|
537
623
|
(r) => r.resourceExists.exists,
|
|
538
624
|
);
|
|
@@ -571,7 +657,7 @@ export class PlTransaction {
|
|
|
571
657
|
ignoreCache: boolean = false,
|
|
572
658
|
): Promise<BasicResourceData | ResourceData> {
|
|
573
659
|
return this.track(async () => {
|
|
574
|
-
if (!ignoreCache &&
|
|
660
|
+
if (!ignoreCache && isResourceId(rId)) {
|
|
575
661
|
// checking if we can return result from cache
|
|
576
662
|
const fromCache = this.sharedResourceDataCache.get(rId);
|
|
577
663
|
if (fromCache && fromCache.cacheTxOpenTimestamp < this.txOpenTimestamp) {
|
|
@@ -592,7 +678,7 @@ export class PlTransaction {
|
|
|
592
678
|
{
|
|
593
679
|
oneofKind: "resourceGet",
|
|
594
680
|
resourceGet: {
|
|
595
|
-
|
|
681
|
+
...this.toSignedResourceId(rId),
|
|
596
682
|
loadFields: loadFields,
|
|
597
683
|
},
|
|
598
684
|
},
|
|
@@ -605,7 +691,7 @@ export class PlTransaction {
|
|
|
605
691
|
|
|
606
692
|
// we will cache only final resource data states
|
|
607
693
|
// caching result even if we were ignore the cache
|
|
608
|
-
if (
|
|
694
|
+
if (isResourceId(rId) && this.finalPredicate(result)) {
|
|
609
695
|
deepFreeze(result);
|
|
610
696
|
const fromCache = this.sharedResourceDataCache.get(rId);
|
|
611
697
|
if (fromCache) {
|
|
@@ -660,8 +746,7 @@ export class PlTransaction {
|
|
|
660
746
|
);
|
|
661
747
|
|
|
662
748
|
// cleaning cache record if resource was removed from the db
|
|
663
|
-
if (result === undefined &&
|
|
664
|
-
this.sharedResourceDataCache.delete(rId);
|
|
749
|
+
if (result === undefined && isResourceId(rId)) this.sharedResourceDataCache.delete(rId);
|
|
665
750
|
|
|
666
751
|
return result;
|
|
667
752
|
});
|
|
@@ -678,7 +763,7 @@ export class PlTransaction {
|
|
|
678
763
|
this._stat.inputsLocked++;
|
|
679
764
|
this.sendVoidAsync({
|
|
680
765
|
oneofKind: "resourceLockInputs",
|
|
681
|
-
resourceLockInputs:
|
|
766
|
+
resourceLockInputs: this.toSignedResourceId(rId),
|
|
682
767
|
});
|
|
683
768
|
}
|
|
684
769
|
|
|
@@ -690,7 +775,7 @@ export class PlTransaction {
|
|
|
690
775
|
this._stat.outputsLocked++;
|
|
691
776
|
this.sendVoidAsync({
|
|
692
777
|
oneofKind: "resourceLockOutputs",
|
|
693
|
-
resourceLockOutputs:
|
|
778
|
+
resourceLockOutputs: this.toSignedResourceId(rId),
|
|
694
779
|
});
|
|
695
780
|
}
|
|
696
781
|
|
|
@@ -703,8 +788,8 @@ export class PlTransaction {
|
|
|
703
788
|
this.sendVoidAsync({
|
|
704
789
|
oneofKind: "resourceSetError",
|
|
705
790
|
resourceSetError: {
|
|
706
|
-
|
|
707
|
-
|
|
791
|
+
...this.toSignedResourceId(rId),
|
|
792
|
+
...this.toSignedErrorRef(ref),
|
|
708
793
|
},
|
|
709
794
|
});
|
|
710
795
|
}
|
|
@@ -717,7 +802,7 @@ export class PlTransaction {
|
|
|
717
802
|
this._stat.fieldsCreated++;
|
|
718
803
|
this.sendVoidAsync({
|
|
719
804
|
oneofKind: "fieldCreate",
|
|
720
|
-
fieldCreate: { type: fieldTypeToProto(fieldType), id:
|
|
805
|
+
fieldCreate: { type: fieldTypeToProto(fieldType), id: this.toSignedFieldId(fId) },
|
|
721
806
|
});
|
|
722
807
|
if (value !== undefined) this.setField(fId, value);
|
|
723
808
|
}
|
|
@@ -726,7 +811,7 @@ export class PlTransaction {
|
|
|
726
811
|
return this.sendSingleAndParse(
|
|
727
812
|
{
|
|
728
813
|
oneofKind: "fieldExists",
|
|
729
|
-
fieldExists: { field:
|
|
814
|
+
fieldExists: { field: this.toSignedFieldId(fId) },
|
|
730
815
|
},
|
|
731
816
|
(r) => r.fieldExists.exists,
|
|
732
817
|
);
|
|
@@ -734,25 +819,26 @@ export class PlTransaction {
|
|
|
734
819
|
|
|
735
820
|
public setField(fId: AnyFieldRef, ref: AnyRef): void {
|
|
736
821
|
this._stat.fieldsSet++;
|
|
737
|
-
if (isResource(ref))
|
|
822
|
+
if (isResource(ref)) {
|
|
738
823
|
this.sendVoidAsync({
|
|
739
824
|
oneofKind: "fieldSet",
|
|
740
825
|
fieldSet: {
|
|
741
|
-
field:
|
|
826
|
+
field: this.toSignedFieldId(fId),
|
|
742
827
|
value: {
|
|
743
|
-
|
|
828
|
+
...this.toSignedResourceId(ref),
|
|
744
829
|
fieldName: "", // default value, read as undefined
|
|
745
830
|
},
|
|
746
831
|
},
|
|
747
832
|
});
|
|
748
|
-
else
|
|
833
|
+
} else {
|
|
749
834
|
this.sendVoidAsync({
|
|
750
835
|
oneofKind: "fieldSet",
|
|
751
836
|
fieldSet: {
|
|
752
|
-
field:
|
|
753
|
-
value:
|
|
837
|
+
field: this.toSignedFieldId(fId),
|
|
838
|
+
value: this.toSignedFieldId(ref),
|
|
754
839
|
},
|
|
755
840
|
});
|
|
841
|
+
}
|
|
756
842
|
}
|
|
757
843
|
|
|
758
844
|
public setFieldError(fId: AnyFieldRef, ref: AnyResourceRef): void {
|
|
@@ -760,8 +846,8 @@ export class PlTransaction {
|
|
|
760
846
|
this.sendVoidAsync({
|
|
761
847
|
oneofKind: "fieldSetError",
|
|
762
848
|
fieldSetError: {
|
|
763
|
-
field:
|
|
764
|
-
|
|
849
|
+
field: this.toSignedFieldId(fId),
|
|
850
|
+
...this.toSignedErrorRef(ref),
|
|
765
851
|
},
|
|
766
852
|
});
|
|
767
853
|
}
|
|
@@ -769,7 +855,7 @@ export class PlTransaction {
|
|
|
769
855
|
public getField(fId: AnyFieldRef): Promise<FieldData> {
|
|
770
856
|
this._stat.fieldsGet++;
|
|
771
857
|
return this.sendSingleAndParse(
|
|
772
|
-
{ oneofKind: "fieldGet", fieldGet: { field:
|
|
858
|
+
{ oneofKind: "fieldGet", fieldGet: { field: this.toSignedFieldId(fId) } },
|
|
773
859
|
(r) => protoToField(notEmpty(r.fieldGet.field)),
|
|
774
860
|
);
|
|
775
861
|
}
|
|
@@ -779,11 +865,17 @@ export class PlTransaction {
|
|
|
779
865
|
}
|
|
780
866
|
|
|
781
867
|
public resetField(fId: AnyFieldRef): void {
|
|
782
|
-
this.sendVoidAsync({
|
|
868
|
+
this.sendVoidAsync({
|
|
869
|
+
oneofKind: "fieldReset",
|
|
870
|
+
fieldReset: { field: this.toSignedFieldId(fId) },
|
|
871
|
+
});
|
|
783
872
|
}
|
|
784
873
|
|
|
785
874
|
public removeField(fId: AnyFieldRef): void {
|
|
786
|
-
this.sendVoidAsync({
|
|
875
|
+
this.sendVoidAsync({
|
|
876
|
+
oneofKind: "fieldRemove",
|
|
877
|
+
fieldRemove: { field: this.toSignedFieldId(fId) },
|
|
878
|
+
});
|
|
787
879
|
}
|
|
788
880
|
|
|
789
881
|
//
|
|
@@ -796,7 +888,7 @@ export class PlTransaction {
|
|
|
796
888
|
{
|
|
797
889
|
oneofKind: "resourceKeyValueList",
|
|
798
890
|
resourceKeyValueList: {
|
|
799
|
-
|
|
891
|
+
...this.toSignedResourceId(rId),
|
|
800
892
|
startFrom: "",
|
|
801
893
|
limit: 0,
|
|
802
894
|
},
|
|
@@ -837,8 +929,7 @@ export class PlTransaction {
|
|
|
837
929
|
this.sendVoidAsync({
|
|
838
930
|
oneofKind: "resourceKeyValueSet",
|
|
839
931
|
resourceKeyValueSet: {
|
|
840
|
-
|
|
841
|
-
resourceSignature: new Uint8Array(0),
|
|
932
|
+
...this.toSignedResourceId(rId),
|
|
842
933
|
key,
|
|
843
934
|
value: toBytes(value),
|
|
844
935
|
},
|
|
@@ -849,8 +940,7 @@ export class PlTransaction {
|
|
|
849
940
|
this.sendVoidAsync({
|
|
850
941
|
oneofKind: "resourceKeyValueDelete",
|
|
851
942
|
resourceKeyValueDelete: {
|
|
852
|
-
|
|
853
|
-
resourceSignature: new Uint8Array(0),
|
|
943
|
+
...this.toSignedResourceId(rId),
|
|
854
944
|
key,
|
|
855
945
|
},
|
|
856
946
|
});
|
|
@@ -862,7 +952,7 @@ export class PlTransaction {
|
|
|
862
952
|
{
|
|
863
953
|
oneofKind: "resourceKeyValueGet",
|
|
864
954
|
resourceKeyValueGet: {
|
|
865
|
-
|
|
955
|
+
...this.toSignedResourceId(rId),
|
|
866
956
|
key,
|
|
867
957
|
},
|
|
868
958
|
},
|
|
@@ -893,7 +983,7 @@ export class PlTransaction {
|
|
|
893
983
|
{
|
|
894
984
|
oneofKind: "resourceKeyValueGetIfExists",
|
|
895
985
|
resourceKeyValueGetIfExists: {
|
|
896
|
-
|
|
986
|
+
...this.toSignedResourceId(rId),
|
|
897
987
|
key,
|
|
898
988
|
},
|
|
899
989
|
},
|
|
@@ -920,7 +1010,7 @@ export class PlTransaction {
|
|
|
920
1010
|
|
|
921
1011
|
public async getKValueJsonIfExists<T>(rId: AnyResourceRef, key: string): Promise<T | undefined> {
|
|
922
1012
|
return this.track(async () => {
|
|
923
|
-
const str = await this.
|
|
1013
|
+
const str = await this.getKValueStringIfExists(rId, key);
|
|
924
1014
|
if (str === undefined) return undefined;
|
|
925
1015
|
return JSON.parse(str) as T;
|
|
926
1016
|
});
|
|
@@ -10,13 +10,17 @@ import { FieldType as GrpcFieldType } from "../proto-grpc/github.com/milaborator
|
|
|
10
10
|
import type {
|
|
11
11
|
FieldData,
|
|
12
12
|
FieldStatus,
|
|
13
|
-
|
|
13
|
+
OptionalSignedResourceId,
|
|
14
14
|
FieldType,
|
|
15
15
|
ResourceData,
|
|
16
|
-
ResourceId,
|
|
17
16
|
ResourceKind,
|
|
18
17
|
} from "./types";
|
|
19
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
createSignedResourceId,
|
|
20
|
+
NullSignedResourceId,
|
|
21
|
+
toResourceSignature,
|
|
22
|
+
NullResourceId,
|
|
23
|
+
} from "./types";
|
|
20
24
|
import { assertNever, notEmpty } from "@milaboratories/ts-helpers";
|
|
21
25
|
import { throwPlNotFoundError } from "./errors";
|
|
22
26
|
|
|
@@ -26,12 +30,20 @@ function resourceIsDeleted(proto: Resource): boolean {
|
|
|
26
30
|
return proto.deletedTime !== undefined && proto.deletedTime.seconds !== 0n;
|
|
27
31
|
}
|
|
28
32
|
|
|
33
|
+
function protoIdToOptionalResourceId(id: bigint, signature?: Uint8Array): OptionalSignedResourceId {
|
|
34
|
+
if (id === NullResourceId) return NullSignedResourceId;
|
|
35
|
+
return createSignedResourceId(id, toResourceSignature(signature));
|
|
36
|
+
}
|
|
37
|
+
|
|
29
38
|
/** Throws "native" pl not found error, if resource is marked as deleted. */
|
|
30
39
|
export function protoToResource(proto: Resource): ResourceData {
|
|
31
40
|
if (resourceIsDeleted(proto)) throwPlNotFoundError("resource deleted");
|
|
32
41
|
return {
|
|
33
|
-
id: proto.resourceId
|
|
34
|
-
originalResourceId:
|
|
42
|
+
id: createSignedResourceId(proto.resourceId, toResourceSignature(proto.resourceSignature)),
|
|
43
|
+
originalResourceId: protoIdToOptionalResourceId(
|
|
44
|
+
proto.originalResourceId,
|
|
45
|
+
proto.originalResourceSignature,
|
|
46
|
+
),
|
|
35
47
|
type: notEmpty(proto.type),
|
|
36
48
|
data: proto.data,
|
|
37
49
|
inputsLocked: proto.inputsLocked,
|
|
@@ -55,9 +67,12 @@ function protoToResourceKind(proto: Resource_Kind): ResourceKind {
|
|
|
55
67
|
throw new Error("invalid ResourceKind: " + proto);
|
|
56
68
|
}
|
|
57
69
|
|
|
58
|
-
function protoToError(proto: Resource):
|
|
70
|
+
function protoToError(proto: Resource): OptionalSignedResourceId {
|
|
59
71
|
const f = proto.fields.find((f) => f?.id?.fieldName === ResourceErrorField);
|
|
60
|
-
|
|
72
|
+
if (!f) return NullSignedResourceId;
|
|
73
|
+
const errId = f.error ?? 0n;
|
|
74
|
+
if (errId === 0n) return NullSignedResourceId;
|
|
75
|
+
return createSignedResourceId(errId, toResourceSignature(f.errorSignature));
|
|
61
76
|
}
|
|
62
77
|
|
|
63
78
|
export function protoToField(proto: Field): FieldData {
|
|
@@ -65,8 +80,8 @@ export function protoToField(proto: Field): FieldData {
|
|
|
65
80
|
name: notEmpty(proto.id?.fieldName),
|
|
66
81
|
type: protoToFieldType(proto.type),
|
|
67
82
|
status: protoToFieldStatus(proto.valueStatus),
|
|
68
|
-
value: proto.value
|
|
69
|
-
error: proto.error
|
|
83
|
+
value: protoIdToOptionalResourceId(proto.value, proto.valueSignature),
|
|
84
|
+
error: protoIdToOptionalResourceId(proto.error, proto.errorSignature),
|
|
70
85
|
valueIsFinal: proto.valueIsFinal,
|
|
71
86
|
};
|
|
72
87
|
}
|